I have DIV tag with text inside. Is it possible to change the text content in a loop with a typing effect, where it types out, then goes backward deleting the letters and starting all over with a new text? Is this possible with jquery?
3 Answers
A simple approach:
const elsTyper = document.querySelectorAll("[data-typer]");
const rand = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
const typer = (el) => {
const text = el.dataset.typer;
const tot = text.length;
let ch = 0;
(function typeIt() {
if (ch > tot) return;
el.textContent = text.substring(0, ch++);
setTimeout(typeIt, rand(60, 300));
}());
};
elsTyper.forEach(typer);
/* PULSATING CARET */
[data-typer]:after {
content:"";
display: inline-block;
vertical-align: middle;
width:1px;
height:1em;
background: #000;
animation: caretPulsate 1s linear infinite;
}
@keyframes caretPulsate {
0% {opacity:1;}
50% {opacity:1;}
60% {opacity:0;}
100% {opacity:0;}
}
<span data-typer="Hi! My name is Al. I will guide you trough the Setup process."></span>
<h3 data-typer="This is another typing animated text"></h3>
So basically get the data-typer
string of your element, insert character by character using a random min-max timeout. The pulsating "caret" is nothing by a CSS3 animated :after
pseudo element of that same SPAN.
See also: Generate random number between two numbers in JavaScript

- 196,159
- 39
- 305
- 313
-
-
1@Alexander ...we are people? ;) haha kidding, I borrowed the term from audio engineering – Roko C. Buljan Feb 21 '13 at 23:24
-
This would be much more performant if `$('.writer')` was cached to a variable first. `var $writer = $('.writer');` – chrisM Apr 29 '14 at 14:43
-
Where does come from the formula `(Math.random()*(300-60+1)+60)` ? – Olivier Boissé Jun 13 '17 at 14:25
-
@oliv37 Simple math. That formula creates rand in min-max range. `Math.random` gives a decimal between 0..1(exclusive). Say we need random int. between 10 and 30, `(rand * 20) + 10` so the first 20 is nothing but `(max-min)` or `(30-10)`. Random (rand * 20) will logically return decimal numbers in the range 0-19.999.... Since we want 20 to be inclusive we do a `+1` like (max-min+1) now we have the range `0 - 20.999..`. Than rise the result by `10` to get ranges `10 - 30.999..`. Than use `Math.floor` or `~~` to floor the result to get **integers** in the perfect `10 - 30` range. – Roko C. Buljan Jun 13 '17 at 16:35
Jquery's text() method lets you set the text of an element.
You would be able to use this to animate the contents by calling this in a loop, giving it the contents that you'd like to see in each frame.
var frames = ['t_', 'ty_', 'typ_', 'type_']
// loop over frames ... inner part reads frame and prints it
// use setInterval, etc.
$('#my-div').text( frames[i] );
I've done more complicated things by splitting the text elements and manipulating the characters but I think in your case it would be overkill.

- 2,045
- 17
- 15
Typing Effect + Erasing Effect + Blinking Cursor
I modified Simon Shahriveri codepan to further add the blinking effect of the cursor. It's compatible with IE also.
Here's the end result: https://codepen.io/jerrygoyal/pen/vRPpGO
HTML:
<h1>
<a href="" class="typewrite" data-period="2000" data-type='[ "Hi, I am Jerry.", "I am Creative.", "I Love Design.", "I Love to Develop." ]'>
<span class="wrap"></span>
</a>
</h1>
CSS:
body {
background-color:#ce6670;
text-align: center;
color:#fff;
padding-top:10em;
}
* { color:#fff; text-decoration: none;}
.wrap{
animation: caret 1s steps(1) infinite;
border-right: 0.08em solid #fff;
padding-right: 1px;
}
@keyframes caret {
50% {
border-color: transparent;
}
}
JS:
var TxtType = function(el, toRotate, period) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = '';
this.tick();
this.isDeleting = false;
};
TxtType.prototype.tick = function() {
var i = this.loopNum % this.toRotate.length;
var fullTxt = this.toRotate[i];
if (this.isDeleting) {
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
this.el.innerHTML = '<span class="wrap">'+this.txt+'</span>';
var that = this;
var delta = 200 - Math.random() * 100;
if (this.isDeleting) { delta /= 2; }
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = true;
} else if (this.isDeleting && this.txt === '') {
this.isDeleting = false;
this.loopNum++;
delta = 500;
}
setTimeout(function() {
that.tick();
}, delta);
};
window.onload = function() {
var elements = document.getElementsByClassName('typewrite');
for (var i=0; i<elements.length; i++) {
var toRotate = elements[i].getAttribute('data-type');
var period = elements[i].getAttribute('data-period');
if (toRotate) {
new TxtType(elements[i], JSON.parse(toRotate), period);
}
}
};
Another way by using just functions instead of js prototypes: https://codepen.io/jerrygoyal/pen/vRPpGO

- 42,508
- 29
- 229
- 225