How to achieve this typing & deleting effect? - javascript

I’d like to replicate this website’s typing & deleting effect: http://www.cantercompanies.com.
I’ve been trying to figure this out using code blocks, HTML, CSS, and JS. However, I can’t seem to get this to work after hours and days of trying.
It’s obviously on my end, as I am fairly new to coding.
I really want this exact typing & deleting effect with blinking cursor. I of course will be using my own logo and fixed text, but need some guidance and help to replicate Canter's example above in the link provided… :-)

You don't need any library,
HTML
<div class="flex">
<p class="header-sub-title" id="word"></p><p class="header-sub-title blink">|</p>
</div>
CSS
#import 'https://fonts.googleapis.com/css?family=Roboto';
html, body {
background-color: #000;
}
h2, a, p {
color: #fff;
font-family: Roboto;
text-decoration: none;
}
p>a {
color: #fd084a;
}
.blink {
animation: blink 0.5s infinite;
}
#keyframes blink{
to { opacity: .0; }
}
.flex {
display: flex;
}
.header-sub-title {
color: #fff;
font-family: "Courier";
font-size: 20px;
padding: 0.1em;
}
JS
const words = ["CSS3.", "HTML5.", "javascript."];
let i = 0;
let timer;
function typingEffect() {
let word = words[i].split("");
var loopTyping = function() {
if (word.length > 0) {
document.getElementById('word').innerHTML += word.shift();
} else {
deletingEffect();
return false;
};
timer = setTimeout(loopTyping, 500);
};
loopTyping();
};
function deletingEffect() {
let word = words[i].split("");
var loopDeleting = function() {
if (word.length > 0) {
word.pop();
document.getElementById('word').innerHTML = word.join("");
} else {
if (words.length > (i + 1)) {
i++;
} else {
i = 0;
};
typingEffect();
return false;
};
timer = setTimeout(loopDeleting, 200);
};
loopDeleting();
};
typingEffect();
Reference:https://codepen.io/haaswill/pen/VKzXvZ

Related

JS script works on codepen but not in WordPress

Been trying to add a typewriter effect, it works great on codepen but not in WP. I've tried to add the code directly to and also to load it as a .js file from the theme's folder, I can see in page-source it's loaded, but the effect isn't executing.
I've checked in console and there's no errors, initially I got an "Uncaught TypeError: Cannot read property 'innerHTML'", so I moved it to my footer.
This is my code:
HTML
<div>
<span id="container">Testing </span> <span id="text"></span><div id="cursor"></div>
</div>
CSS
#container {
display: inline;
vertical-align: middle;
font-family: 'Poppins',Helvetica,Arial,Lucida,sans-serif!important;
font-weight: 500!important;
font-size: 45px!important;
color: #000000!important;
text-align: left!important;
line-height: 1.5em;
}
#text {
display: inline;
vertical-align: middle;
font-family: 'Poppins',Helvetica,Arial,Lucida,sans-serif!important;
font-weight: 500!important;
font-size: 45px!important;
color: #000000!important;
text-align: left!important;
height: 70px;
line-height: 1.5em;
}
#cursor {
display: inline-block;
vertical-align: middle;
width: 3px;
height: 50px;
background-color: #000000;
animation: blink .75s step-end infinite;
}
#keyframes blink {
from, to {
background-color: transparent
}
50% {
background-color: #000000;
}
}
JS
// List of sentences
var _CONTENT = [
"This",
"That",
"These",
"Those"
];
// Current sentence being processed
var _PART = 0;
// Character number of the current sentence being processed
var _PART_INDEX = 0;
// Holds the handle returned from setInterval
var _INTERVAL_VAL;
// Element that holds the text
var _ELEMENT = document.querySelector("#text");
// Cursor element
var _CURSOR = document.querySelector("#cursor");
// Implements typing effect
function Type() {
// Get substring with 1 characater added
var text = _CONTENT[_PART].substring(0, _PART_INDEX + 1);
_ELEMENT.innerHTML = text;
_PART_INDEX++;
// If full sentence has been displayed then start to delete the sentence after some time
if(text === _CONTENT[_PART]) {
// Hide the cursor
_CURSOR.style.display = 'none';
clearInterval(_INTERVAL_VAL);
setTimeout(function() {
_INTERVAL_VAL = setInterval(Delete, 50);
}, 1000);
}
}
// Implements deleting effect
function Delete() {
// Get substring with 1 characater deleted
var text = _CONTENT[_PART].substring(0, _PART_INDEX - 1);
_ELEMENT.innerHTML = text;
_PART_INDEX--;
// If sentence has been deleted then start to display the next sentence
if(text === '') {
clearInterval(_INTERVAL_VAL);
// If current sentence was last then display the first one, else move to the next
if(_PART == (_CONTENT.length - 1))
_PART = 0;
else
_PART++;
_PART_INDEX = 0;
// Start to display the next sentence after some time
setTimeout(function() {
_CURSOR.style.display = 'inline-block';
_INTERVAL_VAL = setInterval(Type, 100);
}, 200);
}
}
// Start the typing effect on load
_INTERVAL_VAL = setInterval(Type, 100);

Add type in animated feature

I wish to create a feature where the letters are typed in between a sentence as it is done in this page .
In the above link there is a sentence inside the banner that says
Create meaningful documents
Create persuasive documents
Create impactful documents
If you notice, the 2nd word is changing while the first and the third word remains the same, can anyone please tell how this animated feature can be achieved
This can be done using javascript. Here is a plugin that i made that types letters using setInterval() function.
Original Demo:
typer = function(e, s, d, t) {
var eI = 0;
var speed = s;
var delay = d;
var eLength = t.length;
var z = 1;
function loop() {
var p = $("<div class='azy-typer-container azy-typer-done'></div>");
var c_t = $("<span class='azy-typer-element'></span>")
var c_b = $("<span class='azy-typer-blinker'>|</span>");
$(".azy-typer-blinker").remove();
p.append(c_t).append(c_b);
$(e).append(p);
interval = setInterval(function() {
c_t.text(t[eI].substring(0, z));
if (z + 1 > t[eI].length) {
clearInterval(interval);
eI = eI + 1;
if (eI + 1 <= t.length) {
z = 0;
setTimeout(loop, d);
}
} else {
z = z + 1;
}
}, s)
}
loop();
}
new typer(".container", 100, 1000, ["Hi there!", "This is a typer demo ", "What do you think about this ?"]);
body {
background: black;
}
span {
font-family: "Courier New";
font-size: 24px;
color: #fff;
font-weight: bold;
}
.azy-typer-blinker {
animation: blink 1s infinite;
}
#keyframes blink {
0% {
color: crimson;
}
50% {
color: transparent;
}
100% {
color: crimson;
}
}
.azy-typer-done {
margin-left: 24px;
}
.azy-typer-done:before {
content: ">>";
color: lightgreen;
font-family: "Courier New";
font-size: 24px;
margin-left: -24px;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container"></div>
You can do some changes to make this code work as you need
typer = function(e, s, d, t) {
var eI = 0;
var speed = s;
var delay = d;
var eLength = t.length;
var z = 1;
function loop() {
var p = $("<div class='azy-typer-container'></div>");
var c_t = $("<span class='azy-typer-element'></span>")
var c_b = $("<span class='azy-typer-blinker'>|</span>");
$(".azy-typer-blinker").remove();
p.append(c_t).append(c_b);
$(e).append(p);
interval = setInterval(function() {
c_t.text(t[eI].substring(0, z));
if (z + 1 > t[eI].length) {
p.addClass("azy-typer-done");
clearInterval(interval);
eI = eI + 1;
if (eI + 1 <= t.length) {
z = 0;
setTimeout(loop, d);
} else {
eI = 0;
z = 0;
setTimeout(loop, d);
}
} else {
z = z + 1;
}
}, s)
}
loop();
}
new typer(".container", 100, 1000, ["Hi there!", "This is a typer demo ", "What do you think about this ?"]);
body {
background: black;
}
span {
font-family: "Courier New";
font-size: 24px;
color: #fff;
font-weight: bold;
}
.azy-typer-blinker {
color: maroon;
}
.azy-typer-container {
display: inline;
}
.azy-typer-done {
display: none;
}
.static {
color: lime;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<span class="static">Static </span>
</div>
The function takes four arguments
The element to which the text is to be appended
The typing speed
The delay for the next item to appear
The text (should be an array)

Stopwatch in seconds and milliseconds

Hi I'm working on a reaction test that checks how fast it takes for the user before they react, and I can't really find what I'm looking for. I was just wondering how to make a simple stopwatch in seconds and milliseconds so I can call the function later in HTML onclick.
Here is my code so far:
HTML
<input type="button" class="first" value="Call" onclick="call function" />
and that's pretty much it... I know HTML, CSS, JavaScript and a little bit jQuery.
Thanks in advance !
As a basic starting point you want to use setInterval to increment the stopwatch, with an additional function to toggle/reset it.
You can then either bind the click handler directly to the button (per below), or - I would tend to recommend you bind it in the Javascript itself (e.g. with .onclick=function(){....})
var s = 0,
ms = 0,
sEl = document.getElementById('s'),
msEl = document.getElementById('ms'),
play = false;
stopwatch = setInterval(function() {
if (!play) return;
if (ms === 99) {
s += 1;
ms = 0;
} else {
ms += 1;
}
update();
}, 1);
function update() {
sEl.innerText = s;
msEl.innerText = ms;
}
function toggle() {
if (!play) {
s = 0, ms = 0;
update();
}
play = !play;
}
body {
font-family: arial;
}
#s {
font-size: 50px;
}
#ms {
font-size: 30px;
display:inline-block;
width:35px;
}
button {
border: 1px solid grey;
background: lightgrey;
padding: 10px 40px;
}
<span id="s">0</span>s <span id="ms">00</span>ms
<br />
<button onclick="toggle();">Toggle</button>

jQuery: Toggling between 3 classes (initially)

I've seen several posts here on SO but they are too specific in functionality and structure, and what I'm looking for is something more universal that I or anyone can use anywhere.
All I need is to have a button that when clicked can cycle between 3 classes. But if the case arises to have to cycle through 4, 5 or more classes, that the script can be easily scaled.
As of this moment I am able to 'cycle' between two classes which is basically more "toggling" than cycling, so for that I have:
HTML:
Toggle classes
<div class="class1">...</div>
jQuery:
$('.toggle').click(function () {
$('div').toggleClass('class1 class2');
});
Here's a simple fiddle of this.
Now, you would (well, I) think that adding a third class to the method would work, but it doesn't:
$('div').toggleClass('class1 class2 class3');
What happens is that the toggling starts happening between class1 and class3 only.
So this is where I have my initial problem: How to have the Toggle button cycle sequentially through 3 classes?
And then: What if someone needs to cycle to 4, 5 or more classes?
You can do this :
$('.toggle').click(function () {
var classes = ['class1','class2','class3'];
$('div').each(function(){
this.className = classes[($.inArray(this.className, classes)+1)%classes.length];
});
});
Demonstration
Here is another approach:
if ($(this).hasClass('one')) {
$(this).removeClass('one').addClass('two');
} else if ($(this).hasClass('two')) {
$(this).removeClass('two').addClass('three');
} else if ($(this).hasClass('three')) {
$(this).removeClass('three').addClass('one');
}
var classes = ['class1', 'class2', 'class3'],
currentClass = 0;
$('.toggle').click(function () {
$('div').removeClass(classes[currentClass]);
if (currentClass + 1 < classes.length)
{
currentClass += 1;
}
else
{
currentClass = 0;
}
$('div').addClass(classes[currentClass]);
});
Something like that should work OK :)
Tinker IO link - https://tinker.io/1048b
This worked for me and I can stack as many as I want, then wrap around easily.
switch($('div.sel_object table').attr('class'))
{
case "A": $('div.sel_object table').toggleClass('A B'); break;
case "B": $('div.sel_object table').toggleClass('B C'); break;
case "C": $('div.sel_object table').toggleClass('C D'); break;
case "D": $('div.sel_object table').toggleClass('D A'); break;
}
Cycles through the index of classes and toggles from one to ther other.
var classes = ['border-top','border-right','border-bottom','border-left'];
var border = 'border-top';
var index = 0;
var timer = setInterval( function() {
var callback = function(response) {
index = ( ++index == 4 ? 0 : index );
$(element).html("text").toggleClass( border + " " + classes[index] );
border = classes[index];
};
}, 1000 );
I converted user3353523's answer into a jQuery plugin.
(function() {
$.fn.rotateClass = function(cls1, cls2, cls3) {
if ($(this).hasClass(cls1)) {
return $(this).removeClass(cls1).addClass(cls2);
} else if ($(this).hasClass(cls2)) {
return $(this).removeClass(cls2).addClass(cls3);
} else if ($(this).hasClass(cls3)) {
return $(this).removeClass(cls3).addClass(cls1);
} else {
return $(this).toggleClass(cls1); // Default case.
}
}
})(jQuery);
$('#click-me').on('click', function(e) {
$(this).rotateClass('cls-1', 'cls-2', 'cls-3');
});
#click-me {
width: 5em;
height: 5em;
line-height: 5em;
text-align: center;
border: thin solid #777;
margin: calc(49vh - 2.4em) auto;
cursor: pointer;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cls-1 { background: #FFAAAA; }
.cls-2 { background: #AAFFAA; }
.cls-3 { background: #AAAAFF; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="click-me" class="unselectable">Click Me!</div>
Dynamic Approach
(function() {
$.fn.rotateClass = function() {
let $this = this,
clsList = arguments.length > 1 ? [].slice.call(arguments) : arguments[0];
if (clsList.length === 0) {
return $this;
}
if (typeof clsList === 'string') {
clsList = clsList.indexOf(' ') > -1 ? clsList.split(/\s+/) : [ clsList ];
}
if (clsList.length > 1) {
for (let idx = 0; idx < clsList.length; idx++) {
if ($this.hasClass(clsList[idx])) {
let nextIdx = (idx + 1) % clsList.length,
nextCls = clsList.splice(nextIdx, 1);
return $this.removeClass(clsList.join(' ')).addClass(nextCls[0]);
}
}
}
return $this.toggleClass(clsList[0]);
}
})(jQuery);
$('#click-me').on('click', function(e) {
$(this).rotateClass('cls-1', 'cls-2', 'cls-3'); // Parameters
//$(this).rotateClass(['cls-1', 'cls-2', 'cls-3']); // Array
//$(this).rotateClass('cls-1 cls-2 cls-3'); // String
});
#click-me {
width: 5em;
height: 5em;
line-height: 5em;
text-align: center;
border: thin solid #777;
margin: calc(49vh - 2.4em) auto;
cursor: pointer;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cls-1 { background: #FFAAAA; }
.cls-2 { background: #AAFFAA; }
.cls-3 { background: #AAAAFF; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="click-me" class="unselectable">Click Me!</div>
HTML:
<div id="example" class="red">color sample</div>
CSS:
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.green {
background-color: green;
}
JS:
$(document).ready(function() {
var colors = ['red', 'yellow', 'green'];
var tmp;
setInterval(function(){
tmp && $('#example').removeClass(tmp);
tmp = colors.pop();
$('#example').addClass(tmp);
colors.unshift(tmp);
}, 1000);
});
DEMO
Another version that uses classList replace. Not supported by all browsers yet.
var classes = ["class1", "class2", "class3"];
var index = 0;
var classList = document.querySelector("div").classList;
const len = classes.length;
$('.toggle').click(function() {
classList.replace(classes[index++ % len], classes[index % len]);
});
.class1 {
background: yellow;
}
.class2 {
background: orange;
}
.class3 {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Toggle classes
<div class="class1">
look at me!
</div>

Pagination Alternatives

I am looking for ideas for pagination alternatives. I am aware of 2 pagination schemes:
Click on pages pagination - my favorite example
Infinite scroll pagination - one implementation here that seems to work
There must be some other less known/popular ways to do it. Bonus points if you can provide a link to a demo
Thanks
I think that a good alternative to paging is a way, or more than one way, for the user to tell the server something about what it is they're looking for. For some types of content (like, a whole lot of text, say from a research paper or a work of fiction), of course you're probably stuck with paging. But when the content is naturally searchable (like tables of checking account transactions), good, simple filtering tools are probably more useful than pagination schemes. (Actually you may need both.)
I worked on a GWT hybrid technique where it did an "infinite scroll" but only showed a "window/page" of information at a time. So it only loaded a fixed amount of data to the browser at any given time. If you could display 20 items and scrolled it just updated the list 20 items at a time. Paging without paging, scrolling without scrolling.
Of course this is a trivial definition of the actual implementation, which was much smarter than this sounds and very optimized for round trips. And this was a list of results that was already filtered down with search criteria. They go hand in hand.
Take a look at 'logarithmic' pagination, as described in my answer here:
How to do page navigation for many, many pages? Logarithmic page navigation
It's like regular pagination, but solves the problem of getting to pages in the middle of a '...' range without many repeated mouseclicks. i.e. How long would it take to get to page 2456 out of 10380 if these are your links: 1 2 3 4 5 ... 10376 10377 10378 10379 10380 ?
(But, Pointy has, uhm... a point also (!))
Here is the code for a pure JavaScript pagination control I built recently. It is similar to your favorite with these added benefits...
Clicking the ... allows quick jump to any page
No words means no localization (next, prev, first, last buttons aren't
needed in this simple control)
No dependencies (jQuery not required)
var Pagination = {
code: '',
Extend: function(data) {
data = data || {};
Pagination.size = data.size || 300;
Pagination.page = data.page || 1;
Pagination.step = data.step || 3;
},
Add: function(s, f) {
for (var i = s; i < f; i++) {
Pagination.code += '<a>' + i + '</a>';
}
},
Last: function() {
Pagination.code += '<i>...</i><a>' + Pagination.size + '</a>';
},
First: function() {
Pagination.code += '<a>1</a><i>...</i>';
},
Click: function() {
Pagination.page = +this.innerHTML;
Pagination.Start();
},
Prev: function() {
Pagination.page--;
if (Pagination.page < 1) {
Pagination.page = 1;
}
Pagination.Start();
},
Next: function() {
Pagination.page++;
if (Pagination.page > Pagination.size) {
Pagination.page = Pagination.size;
}
Pagination.Start();
},
TypePage: function() {
Pagination.code = '<input onclick="this.setSelectionRange(0, this.value.length);this.focus();" onkeypress="if (event.keyCode == 13) { this.blur(); }" value="' + Pagination.page + '" /> / ' + Pagination.size;
Pagination.Finish();
var v = Pagination.e.getElementsByTagName('input')[0];
v.click();
v.addEventListener("blur", function(event) {
var p = parseInt(this.value);
if (!isNaN(parseFloat(p)) && isFinite(p)) {
if (p > Pagination.size) {
p = Pagination.size;
} else if (p < 1) {
p = 1;
}
} else {
p = Pagination.page;
}
Pagination.Init(document.getElementById('pagination'), {
size: Pagination.size,
page: p,
step: Pagination.step
});
}, false);
},
Bind: function() {
var a = Pagination.e.getElementsByTagName('a');
for (var i = 0; i < a.length; i++) {
if (+a[i].innerHTML === Pagination.page) a[i].className = 'current';
a[i].addEventListener('click', Pagination.Click, false);
}
var d = Pagination.e.getElementsByTagName('i');
for (i = 0; i < d.length; i++) {
d[i].addEventListener('click', Pagination.TypePage, false);
}
},
Finish: function() {
Pagination.e.innerHTML = Pagination.code;
Pagination.code = '';
Pagination.Bind();
},
Start: function() {
if (Pagination.size < Pagination.step * 2 + 6) {
Pagination.Add(1, Pagination.size + 1);
} else if (Pagination.page < Pagination.step * 2 + 1) {
Pagination.Add(1, Pagination.step * 2 + 4);
Pagination.Last();
} else if (Pagination.page > Pagination.size - Pagination.step * 2) {
Pagination.First();
Pagination.Add(Pagination.size - Pagination.step * 2 - 2, Pagination.size + 1);
} else {
Pagination.First();
Pagination.Add(Pagination.page - Pagination.step, Pagination.page + Pagination.step + 1);
Pagination.Last();
}
Pagination.Finish();
},
Buttons: function(e) {
var nav = e.getElementsByTagName('a');
nav[0].addEventListener('click', Pagination.Prev, false);
nav[1].addEventListener('click', Pagination.Next, false);
},
Create: function(e) {
var html = [
'<a>◄</a>', // previous button
'<span></span>', // pagination container
'<a>►</a>' // next button
];
e.innerHTML = html.join('');
Pagination.e = e.getElementsByTagName('span')[0];
Pagination.Buttons(e);
},
Init: function(e, data) {
Pagination.Extend(data);
Pagination.Create(e);
Pagination.Start();
}
};
var init = function() {
Pagination.Init(document.getElementById('pagination'), {
size: 30, // pages size
page: 1, // selected page
step: 2 // pages before and after current
});
};
document.addEventListener('DOMContentLoaded', init, false);
html {
height: 100%;
width: 100%;
background-color: #ffffff;
}
body {
margin: 0;
height: 100%;
width: 100%;
text-align: center;
font-family: Arial, sans-serif;
}
body:before {
content: '';
display: inline-block;
width: 0;
height: 100%;
vertical-align: middle;
}
#pagination {
display: inline-block;
vertical-align: middle;
padding: 1px 2px 4px 2px;
font-size: 12px;
color: #7D7D7D;
}
#pagination a,
#pagination i {
display: inline-block;
vertical-align: middle;
width: 22px;
color: #7D7D7D;
text-align: center;
padding: 4px 0;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
#pagination a {
margin: 0 2px 0 2px;
cursor: pointer;
}
#pagination a:hover {
background-color: #999;
color: #fff;
}
#pagination i {
border: 2px solid transparent;
cursor: pointer;
}
#pagination i:hover {
border: 2px solid #999;
cursor: pointer;
}
#pagination input {
width: 40px;
padding: 2px 4px;
color: #7D7D7D;
text-align: right;
}
#pagination a.current {
border: 1px solid #E9E9E9;
background-color: #666;
color: #fff;
}
<div id="pagination"></div>
There's a cool logarithmic pagination solution here:
http://jobcloud.cz/glPagiSmart.jc
But I'm not sure how many people would actually want to use the hex or binary implementations :)

Categories