Reputation: 17
I have a code that is supposed to show some text in a typewriter effect, but the console says that length is not defined. I do not know what to do, please help me.
function typeWriter(theX) {
var i = 0;
text = theX;
var leng = text.length;
if (i < leng) {
document.getElementById("theTexts").innerHTML += text.charAt(i);
setTimeout(typeWriter, speed);
}
}
var speed = 50;
typeWriter('Frog-E Console');
var speed = 60;
typeWriter('Booting up');
Upvotes: 0
Views: 167
Reputation: 1074839
Some issues:
setTimeout
calls your typeWriter
function, it won't pass it a value for theX
so you end up with theX
being undefined
, so text
is undefined
, so you get the error.typeWriter
call won't wait until the previous one finishes before starting, so they'll stomp on each other. You can fix that by having typeWriter
return a promise it fulfills when it's done.text
variable is undeclared, making it what I call an implicit global; we don't need that variable, so let's just ditch it.speed
in rather than using a global.Rather than having setTimeout
call typeWriter
directly, I'd probably use an inner function. See comments:
// Accept both text and speed
function typeWriter(text, speed) {
// Return a promise we'll fulfill when done
return new Promise(resolve => {
// Start out showing nothing
let currentLength = 0;
// Start the process by showing the first character
tick();
function tick() {
// Add one to what we're showing
++currentLength;
// Show it
document.getElementById("theTexts").innerHTML = text.substring(0, currentLength);
// Done?
if (currentLength === text.length) {
// Yes, fulfill the promise
resolve();
} else {
// No, keep going after a delay
setTimeout(tick, speed);
}
}
});
}
// Do the first one, wait for it to finish, then do the next
typeWriter("Frog-E Console", 50)
.then(() => {
return typeWriter("Booting up", 60);
});
<div id="theTexts"></div>
Upvotes: 1
Reputation: 26390
By calling setTimeout(typeWriter, speed)
you are calling typeWriter
without passing it anything. This function expect one argument (a string), so you need to pass it :
function typeWriter(theX) {
var i = 0;
text = theX;
var leng = text.length;
if (i < leng) {
document.getElementById("theTexts").innerHTML += text.charAt(i);
setTimeout(typeWriter.bind(this, text), speed);
}
}
var speed = 50;
typeWriter('Frog-E Console');
var speed = 60;
typeWriter('Booting up');
<div id="theTexts"></div>
However this doesn't produce the expected result, you should do something like this :
function typeWriter(text) {
const char = text[0]
theTexts.innerHTML += char;
if (text.length > 1) setTimeout(typeWriter.bind(this, text.substring(1)), speed);
}
var speed = 50;
typeWriter('Frog-E Console');
<div id="theTexts"></div>
Upvotes: 1