1

I'm trying to get this loop to work in javascript so it opens and closes an accordion at different intervals.... It only runs the loop once and stops. I'm banging my head against the wall as to why?

var i;

i = 0;

while (i < 999) {
  setTimeout((function() {
    return $("#money-slide").collapse("show");
  }), 0);
  setTimeout((function() {
    return $("#money-slide").collapse("hide");
  }), 4000);
  setTimeout((function() {
    return $("#collaboration-slide").collapse("show");
  }), 4000);
  setTimeout((function() {
    return $("#collaboration-slide").collapse("hide");
 }), 8000);
  setTimeout((function() {
    return $("#efficiency-slide").collapse("show");
  }), 8000);
  setTimeout((function() {
    return $("#efficiency-slide").collapse("hide");
  }), 12000);
  setTimeout((function() {
    return $("#communication-slide").collapse("show");
  }), 12000);
  setTimeout((function() {
    return $("#communication-slide").collapse("hide");
  }), 16000);
  i++;
} 
  • 1
    If you add console.log(i) into your loop, you should see that it does run multiple times. – Douglas Jun 06 '13 at 20:11
  • 1
    It's because JavaScript doesn't wait for the timeout to complete before moving onto the next event. Basically, it's running through your loop 999 times and setting all the timeouts at once. You can probably put the `i++;` inside the last timeout function so it doesn't iterate until that timeout fires. – jmiraglia Jun 06 '13 at 20:12
  • yes I inserted a console.log(i) and see it's running without pause for the timeout. How do I prevent that? – user2461174 Jun 06 '13 at 20:22
  • @jasonmmiraglia, you cannot put the `i++` inside the timeout function to change how the loop iterates. – Riley Lark Jun 06 '13 at 20:30

3 Answers3

3

Use

setInterval

instead of

setTimeout

Also setTimeout ot setIterval are async , so returning anything from it won't do anything.

Try this

var i = 0;

var timer1, timer2, timew3, timer4, timer5, timer6, timer7, timer8;

setAnimationIntervals();



i = 0;

function setAnimationIntervals() {
    timer1 = setInterval((function () {
        $("#money-slide").collapse("show");
    }), 0);
    timer2 = setInterval((function () {
        $("#money-slide").collapse("hide");
    }), 4000);
    timer3 = setInterval((function () {
        $("#collaboration-slide").collapse("show");
    }), 4000);
    timer4 = setInterval((function () {
        return $("#collaboration-slide").collapse("hide");
    }), 8000);
    timer5 = setInterval((function () {
        $("#efficiency-slide").collapse("show");
    }), 8000);
    timer6 = setInterval((function () {
        $("#efficiency-slide").collapse("hide");
    }), 12000);
    timer7 = setInterval((function () {
        $("#communication-slide").collapse("show");
    }), 12000);
    timer8 = setInterval((function () {
        $("#communication-slide").collapse("hide");
        i++;
        if (i === 999) {
            clearAnimationIntervals();
        }
    }), 16000);
}

function clearAnimationIntervals {
    clearInterval(timer1);
    clearInterval(timer2);
    clearInterval(timer3);
    clearInterval(timer4);
    clearInterval(timer5);
    clearInterval(timer6);
    clearInterval(timer7);
    clearInterval(timer8);
}
Sushanth --
  • 55,259
  • 9
  • 66
  • 105
  • Using `setInterval` will keep the animation from ending after 999 times. – jmiraglia Jun 06 '13 at 20:16
  • With this code you will have `#money-slide` collapse and open 4 times by the time `#communication-slide` collapses and opens once. I don't think that's what OP is looking to do. Also, `timer1` is going to continuously fire. – jmiraglia Jun 07 '13 at 11:59
0

the reason why it does it once is because you schedule so many timeouts in a loop, and then they all run simultaneously, and when each one is executed, it just stops. You would need to create another timeout from the timeout callback, or use setInterval.

Something along the lines of (not tested):

var money_slide_visible = false;
var money_slide_handler = function () {
    $("#money-slide").collapse(money_slide_visible ? 'hide' : 'show');
    money_slide_visible = !money_slide_visible;
    setInterval(money_slide_handler, 4000);
};

money_slide_handler();
akonsu
  • 28,824
  • 33
  • 119
  • 194
0

Instead of setting your time-outs when the previous time-out has ended, you set all 999 time outs at once.

You need to set a new time-out in the time-out function. Or better use setInterval

Michiel
  • 4,160
  • 3
  • 30
  • 42