Reputation: 551
I'm trying to create a js object with a method which will print letter by letter with a 5 sec delay between each letter. But right now is not running. It writes it with no delay. Where is my error?
class autoWrite{
constructor(id,text){
this.id = id;
this.text = text;
}
startTyping(index=0){
if(index==this.text.length){
console.log("finish");
}
else{
$("#"+this.id).append(this.text.charAt(index));
setTimeout(this.startTyping(index+1),5000);
}
}
}
a = new autoWrite("body-window","hello world");
a.startTyping();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="body-window">
</div>
Upvotes: 1
Views: 98
Reputation: 10614
Do this instead:
class autoWrite{
constructor(id,text){
this.id = id;
this.text = text;
}
startTyping(index=0){
if(index==this.text.length){
console.log("finish");
}
else{
$("#"+this.id).append(this.text.charAt(index));
console.log(this.text.charAt(index))
setTimeout(() => this.startTyping(index+1), 500);
}
}
}
a = new autoWrite("body-window","hello world");
a.startTyping();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="body-window">
</div>
Alternatively, you can use setInterval()
like this (better approach):
class autoWrite{
constructor(id,text){
this.id = id;
this.text = text;
this.index = 0;
}
startTyping(){
if(this.index==this.text.length){
console.log("finish");
this.index += 1;
} else { $("#"+this.id).append(this.text.charAt(this.index));
console.log(this.text.charAt(this.index));
this.index += 1;
}
}
start(){
setInterval(() => {
if(this.index <= this.text.length){
this.startTyping();
}
}, 500);
}
}
a = new autoWrite("body-window","hello world");
a.start();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="body-window">
</div>
Upvotes: 3
Reputation: 839
As stated in the documentation of setTimeout by MDN here, the first argument is the reference to the function you need to execute after the delay.
You can use the following code.
class autoWrite{
constructor(id,text){
this.id = id;
this.text = text;
}
startTyping(index=0){
if(index==this.text.length){
console.log("finish");
}
else{
$("#"+this.id).append(this.text.charAt(index));
let obj = this;
setTimeout(function () {
obj.startTyping(index+1);
},5000);
}
}
}
a = new autoWrite("body-window","hello world");
a.startTyping();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="body-window">
</div>
Upvotes: 1
Reputation: 152216
With
setTimeout(this.startTyping(index+1),5000);
you're passing the result of startTyping
as a function to be invoked with setTimeout
- which is undefined
- it is also invoked immediately with no delay. Try with:
var that = this;
setTimeout(function() {
that.startTyping(index+1);
}, 5000);
Upvotes: 5