Reputation: 387
I want to have a type writer effect on my website. Such that it repeats the data in array infinite times not just once.
I tried to build one with JS but it's only showing data in the array only one time.
For example I have an array :
var dataText = [ "Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];
I want it to be shown like this :
Amsterdam
Full Service.
Webdevelopment
Vivank
Amsterdam
Full Service.
Webdevelopment
Vivank
Amsterdam
Full Service.
Webdevelopment
Vivank.....
upto many times
What my code is doing it stops after one cycle. I want it to repeat cycle unlimited times.
Also, I am getting some kind of error.
Error: { "message": "Script error.", "filename": "", "lineno": 0, "colno": 0 }
Any Help?
Also how to add a pause to animation so that it starts to alter the text in p
after a minute ?
Here is what i have tried so far :
document.addEventListener('DOMContentLoaded',function(event){
// array with texts to type in typewriter
var dataText = [ "Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];
// type one text in the typwriter
// keeps calling itself until the text is finished
function typeWriter(text, i, fnCallback) {
// chekc if text isn't finished yet
if (i < (text.length)) {
// add next character to h1
document.querySelector("#tw").innerHTML = text.substring(0, i+1) +'<span aria-hidden="true"></span>';
// wait for a while and call this function again for next character
setTimeout(function() {
typeWriter(text, i + 1, fnCallback)
}, 100);
}
// text finished, call callback if there is a callback function
else if (typeof fnCallback == 'function') {
// call callback after timeout
setTimeout(fnCallback, 700);
}
}
// start a typewriter animation for a text in the dataText array
function StartTextAnimation(i) {
if (typeof dataText[i] == 'undefined'){
setTimeout(function() {
StartTextAnimation(0);
}, 20000);
}
// check if dataText[i] exists
if (i < dataText[i].length) {
// text exists! start typewriter animation
typeWriter(dataText[i], 0, function(){
// after callback (and whole text has been animated), start next text
StartTextAnimation(i + 1);
});
}
}
// start the text animation
StartTextAnimation(0);
});
<p id="tw">A</p>
Upvotes: 2
Views: 1321
Reputation: 1369
You already have the condition to check for undefined index, but you missed the additional condition to restart your sequence.
Also, you have some poor choice of variable names, namely, index "i" in both functions can be confusing, as one function iterates over words in array, and the other one over characters.
I've rewritten your functions and make the entire code more production-friendly and human-readable of what-is-going-on:
// array with text to type in typewriter
var dataText = [
"Web Design.",
"Web Development.",
"Web Programming."
];
// typewriter speed
// set delay time between each character typing time
var CharDelay = 50;
// pause time between each completed word (delay before next word starts)
var WordPause = 1000;
// set initial word in dataText array
var WordOffset = 0;
// set sequence restart interval N [ms]
var RestartInterval = 3000;
// type one text in the typewriter
// keeps calling itself until complete word is printed
function typeWriter(text, i, fnCallback) {
// check if word isn't finished yet
if (i < (text.length)) {
// add next character to html
document.querySelector("#typewriter").innerHTML = text.substring(0, i+1) + '<span aria-hidden="true"></span>';
// wait for a while and call this function again for next character
setTimeout(function() {
typeWriter(text, i+1, fnCallback)
}, CharDelay);
}
// text finished, call callback if there is a callback function
else if (typeof fnCallback == 'function') {
// call callback after timeout
setTimeout(fnCallback, WordPause);
}
}
// start a typewriter animation in the dataText array
// @param int j = dataText array word index
function StartTextAnimation(j) {
//console.log(j);
//console.log(dataText.length);
// restart animation after N seconds
if (typeof dataText[j] == 'undefined' || j == dataText.length) {
setTimeout(function() {
StartTextAnimation(WordOffset);
}, RestartInterval);
}
// check if dataText[j] exists
else if (j < dataText[j].length) {
// text exists! start typewriter animation
typeWriter(dataText[j], 0, function() {
// after callback (and whole text has been animated), start next word
StartTextAnimation((j+1));
});
}
}
document.addEventListener('DOMContentLoaded', function(event) {
// start text animation
StartTextAnimation(WordOffset);
});
<div id="typewriter"></div>
Upvotes: 1
Reputation: 370729
All you need to do is pass the i
(the index of the item you're iterating over) modulo dataText.length
, to ensure that once i
reaches dataText.length
, StartTextAnimation
gets called with 0
rather than an index which doesn't exist:
StartTextAnimation((i + 1) % dataText.length);
document.addEventListener('DOMContentLoaded',function(event){
// array with texts to type in typewriter
var dataText = [ "Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];
// type one text in the typwriter
// keeps calling itself until the text is finished
function typeWriter(text, i, fnCallback) {
// chekc if text isn't finished yet
if (i < (text.length)) {
// add next character to h1
document.querySelector("#tw").innerHTML = text.substring(0, i+1) +'<span aria-hidden="true"></span>';
// wait for a while and call this function again for next character
setTimeout(function() {
typeWriter(text, i + 1, fnCallback)
}, 100);
}
// text finished, call callback if there is a callback function
else if (typeof fnCallback == 'function') {
// call callback after timeout
setTimeout(fnCallback, 700);
}
}
// start a typewriter animation for a text in the dataText array
function StartTextAnimation(i) {
if (typeof dataText[i] == 'undefined'){
setTimeout(function() {
StartTextAnimation(0);
}, 20000);
}
// check if dataText[i] exists
if (i < dataText[i].length) {
// text exists! start typewriter animation
typeWriter(dataText[i], 0, function(){
// after callback (and whole text has been animated), start next text
StartTextAnimation((i + 1) % dataText.length);
});
}
}
// start the text animation
StartTextAnimation(0);
});
<p id="tw">A</p>
Or, for a large delay after a full loop is done, use else if
after the undefined
check instead of if
:
if (dataText[i] === undefined) {
setTimeout(function() {
StartTextAnimation(0);
}, 20000);
} else if (i < dataText[i].length) {
// text exists! start typewriter animation
typeWriter(dataText[i], 0, function() {
// after callback (and whole text has been animated), start next text
StartTextAnimation(i + 1);
});
}
document.addEventListener('DOMContentLoaded', function(event) {
// array with texts to type in typewriter
var dataText = ["Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];
// type one text in the typwriter
// keeps calling itself until the text is finished
function typeWriter(text, i, fnCallback) {
// chekc if text isn't finished yet
if (i < (text.length)) {
// add next character to h1
document.querySelector("#tw").innerHTML = text.substring(0, i + 1) + '<span aria-hidden="true"></span>';
// wait for a while and call this function again for next character
setTimeout(function() {
typeWriter(text, i + 1, fnCallback)
}, 100);
}
// text finished, call callback if there is a callback function
else if (typeof fnCallback == 'function') {
// call callback after timeout
setTimeout(fnCallback, 700);
}
}
// start a typewriter animation for a text in the dataText array
function StartTextAnimation(i) {
if (dataText[i] === undefined) {
setTimeout(function() {
StartTextAnimation(0);
}, 20000);
} else if (i < dataText[i].length) {
// text exists! start typewriter animation
typeWriter(dataText[i], 0, function() {
// after callback (and whole text has been animated), start next text
StartTextAnimation(i + 1);
});
}
}
// start the text animation
StartTextAnimation(0);
});
<p id="tw">A</p>
Upvotes: 2