hanz
hanz

Reputation: 3

Jquery looping through text, displaying on screen

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

Answers (1)

aviraldg
aviraldg

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

Related Questions