Reputation: 3
I have the following code to loop through a list of text, and fade each piece of text in and out of the div. Currently, as soon as i refresh the page, only the last element of the list (txt[4]) fades into the screen, almost like it runs through the while loop instantly without displaying anything on the screen.
var txt = ["txt1","txt2","txt3","txt4","txt5"]
var ctr = 0
$(document).ready(function() {
while(ctr < 5){
setTimeout(placeText(),1200)
ctr++;
fadeIn()
setTimeout(fadeOut(),1200)
}
});
function placeText() {
$("#fader").text(txt[ctr])
console.log("placed")
}
function fadeIn(){
$("#fader").delay(800).animate({
"opacity": "1"
}, 1200,);
}
function fadeOut(){
$("#fader").delay(800).animate({
"opacity": "0"
}, 1200,);
}
Upvotes: 0
Views: 196
Reputation: 9154
There are two issues here:
setTimeout
expects a callback as a parameter, but in your code (setTimeout(placeText(),1200)
) you're invoking your callback immediately instead of providing it as parameter. It should be setTimeout(placeText,1200)
.
If the above were fixed:
setTimeout
does not block execution of your code until the timeout expires; it schedules the callback to be invoked once the timeout expires. Due to this, all of your callbacks are scheduled to be executed ~1200ms in the future, which is not what you want.
To have them execute sequentially, you could compute timeouts (eg. 1200 for the first one, 1200*3 [plus delays] for the second one, and so on), but that gets cumbersome quickly. Ideally, this code could be written using async/await and Promises somewhat like so:
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
async function() {
while(ctr < 5){
await wait(1200);
placeText();
ctr++;
await fadeIn();
await wait(1200);
await fadeOut();
}
}
// Make similar changes to the other functions
async function fadeOut(){
return $("#fader").delay(800).animate({
"opacity": "0"
}, 1200).promise();
}
Upvotes: 1