I had an approach to add a typewriter effect to my text using Javascript
. I used the following snippet to do so :
const text = document.querySelector('.type')
const content = text.textContent
let counter = 0
text.textContent = ''
while (counter < content.length) {
setTimeout(function () {
text.textContent += content[counter];
counter += 1
}, 1000)
}
I know that this approach seems ridiculous , but I'm curious why it does this. When I try to run this snippet, the browser (Chrome) becomes not responding. I want to know if this code generates an infinite loop, and why? And if someone can provide me some alternative way to get the wanted result.
Thanks to @Martijn & @Alex Brohshtut for helping me recognize the problem and offering helpful solutions.
I did maintain my code using their notices and by looking up through the internet and finally I did it in that way:
const text = document.querySelector('.type')
const content = text.textContent
let counter = 0
text.textContent = ''
while (counter < content.length) {
setTimeout((function (counterCopy) {
return function () {
text.textContent += content[counterCopy];
}
}(counter)), 1000 * counter++)
}
I modified the value of the variable counter
only inside the callback function of setTimeout
, and its value didn't change inside the loop due to scope reasons. So it was an infinite loop which made my browser not responding for a night.
solution: I had to change the value of counter
outside the callback function
I misunderstood the setTimeout
function, thought it would make script stop for a time and then continue. The two friends showed me that it only schedules the callback function inside it to be executed after a specific time. So, I had to increase that time in every iteration.
solution: I took @Martijn's advice and used 1000 * counter++
as a time for it.
When I make the function inside setTimeout
get executed after 1000 ms, the loop continues and increases the value of counter
. so when the function gets executed, the counter now has its highest value which is equal to content.length
.
solution: I used a function call which returns the callback function itself, but this time with the counter as an argument to it. This looked for me a bit confusing but it worked fine at the end.
setTimeout((function(counterCopy){
return function() {
console.log(counterCopy)
}
}(counter)), 1000 * counter++)
Using setInterval
instead of setTimeout
:
const text = document.querySelector('.type')
const content = text.textContent
let counter = 0
text.textContent = ''
var typewriter = setInterval(function(){
text.textContent += content[counter];
counter++;
if (counter > (content.length - 1)) {
clearInterval(typewriter);
}
}, 1000);