I'm trying to create a "typewriter" function and use it to define a variable, so that each character is added individually based on a timeout function. The issue is it is only defining the very first character of the text.
<!DOCTYPE html>
<html>
<body>
<h1>Typewriter</h1>
<p id="demo"></p>
<script>
var i = 0;
var txt = 'Lorem ipsum dummy text blabla.';
var speed = 50;
var x = "" ;
x = typeWriter() ;
function typeWriter() {
if (i < txt.length) {
x += txt.charAt(i) ;
i++;
setTimeout(typeWriter, speed);
return x ;
}
}
document.getElementById("demo").innerHTML = x ;
</script>
</body>
</html>
** This is based on W3School's typewwriter How-To example. www.w3schools.com **
You had a few mistakes:
most importantly, and the reason you were seeing no updates: the line document.getElementById("demo").innerHTML = x; was running only once, when the page first loaded. Your typeWriter function was updating x, but the value of x was never being reflected back in the UI
you don't want to set x = typeWriter(), as this overwrites the empty string that you correctly initially set x as, and means your function is trying to add a 1-character string to a function, which will produce a nonsensical result. You don't care about what typeWriter returns (which is why I've also removed the return x from it - that line does no harm but is completely irrelevant anyway), you just want to execute it, so I've replaced that line with simply typeWriter(). The important part is that now x starts off as the empty string, as you want.
See working version here with the above points fixed:
<!DOCTYPE html>
<html>
<body>
<h1>Typewriter</h1>
<p id="demo"></p>
<script>
var i = 0;
var txt = 'Lorem ipsum dummy text blabla.';
var speed = 50;
var x = "" ;
typeWriter() ;
function typeWriter() {
if (i < txt.length) {
x += txt.charAt(i) ;
i++;
setTimeout(typeWriter, speed);
document.getElementById("demo").innerHTML = x ;
}
}
</script>
</body>
</html>
Other way to do the same:
<!DOCTYPE html>
<html>
<body>
<h1>Typewriter</h1>
<p id="demo"></p>
<script>
var txt = 'Lorem ipsum dummy text blabla.';
Array.from(txt).map((v,i,a)=>{setTimeout(()=>{document.getElementById("demo").innerHTML+=v;},50*(i+1));})
</script>
</body>
</html>