0

I try to loop some div's, and I have that code:

var first = ".first";
for (i = 0; i < 9999; i++) {
    setTimeout(function () {
        $(first).delay(500).animate({
            "opacity": "1"
        }, 1500);
        $(first).delay(1500).animate({
            "opacity": "0"
        }, 1500);
        $(".1").delay(4500).animate({
            "opacity": "1"
        }, 1500);
        $(".1").delay(1500).animate({
            "opacity": "0"
        }, 1500);

        $(".2").delay(4800).animate({
            "opacity": "1"
        }, 1500);
        $(".2").delay(1500).animate({
            "opacity": "0"
        }, 1500);

        $(".3").delay(5300).animate({
            "opacity": "1"
        }, 1500);
        $(".3").delay(1500).animate({
            "opacity": "0"
        }, 1500);

        $(".4").delay(5600).animate({
            "opacity": "1"
        }, 1500);
        $(".4").delay(1500).animate({
            "opacity": "0"
        }, 1500);

        $(".5").delay(5900).animate({
            "opacity": "1"
        }, 1500);
        $(".5").delay(1500).animate({
            "opacity": "0"
        }, 1500);
    }, 6000);
}

I tried without setTimeout and effect was the same - divs was appeared and disappeared only in 1st loop. In each next loop they're appeared in random order. I know, that method is wrong, but I'm green with JavaScript and I have no idea how to do it correct. Someone can help me?

ComFreek
  • 29,044
  • 18
  • 104
  • 156
Wojciech Parys
  • 339
  • 2
  • 18
  • 1
    animate works asynchronously, thus they all start working at the same moment for you. There's a third argument you can pass to animate, is callback, an anonymous function that does something when animation completed, try to make something with that – deb0rian Nov 20 '13 at 18:34
  • possible duplicate of [Passing functions to setTimeout in a loop: always the last value?](http://stackoverflow.com/questions/6425062/passing-functions-to-settimeout-in-a-loop-always-the-last-value) and a gazillion others – Matt Ball Nov 20 '13 at 18:34
  • could you explain what effect are you trying to get – Techsin Nov 20 '13 at 18:35
  • @MattBall I disagree, the OP does not use any variables in setTimeout's callback function (except `first` which does not change anyway). – ComFreek Nov 20 '13 at 18:36
  • @MattBall OP is not passing any value – A. Wolff Nov 20 '13 at 18:36
  • People, please answer the questions at box below, to remove them from unanswered list. – saulotoledo Nov 20 '13 at 18:36
  • also, you can try using .promise() to make your animation go step by step. – Kyle Yeo Nov 20 '13 at 18:36
  • using timeout like this in a loop gives the feeling that only one is fired because your loop takes nano second to execute. UPDATE: see @epascarello's answer (and upvote it...) – A. Wolff Nov 20 '13 at 18:39

3 Answers3

1

It is because the for loop keep attaching events and you are 9999 animations to the same element with no delay. They are just pounding on each other. The code makes no sense.

If you want the code to run in a loop, you can use a callback in one of the animations and call a function when it is done. Other option is to use a Interval, but that gets messy with timing events not being accurate and they can pile up.

epascarello
  • 204,599
  • 20
  • 195
  • 236
0

It seems like you're trying to make the elements animate seemingly indefinitely by running a setTimeout timer a large number of times. For that you should instead use setInterval() to have the function run every 6 seconds.

So, instead of...

for (i = 0; i < 9999; i++) {
    setTimeout(function () {
        $(first).delay(500).animate({
            "opacity": "1"
        }, 1500);

        // etc etc

    }, 6000);
}

...do this:

setInterval(function () {
    $(first).delay(500).animate({
        "opacity": "1"
    }, 1500);

    // etc etc

}, 6000);

(note: no for loop.)

Demo: http://jsfiddle.net/57sYA/

JJJ
  • 32,902
  • 20
  • 89
  • 102
  • `setInterval` should not be used for this purpose. It assumes that the async code that jQuery runs internally will remain perfectly in sync with your `setInterval`, which is highly unlikely. – Blue Skies Nov 20 '13 at 18:46
  • @BlueSkies I don't see why they should stay in sync in this case. – JJJ Nov 20 '13 at 18:47
  • @BlueSkies Ok, the `delay()` + animation duration is longer than the interval length for most of the elements, which probably messes up the intended effect. – JJJ Nov 20 '13 at 18:49
0

I have found solution of my problem - setInterval

    var licznik=0;
function show_anim(){
         if(licznik!=9999){
         $("#first").delay(500).animate({"opacity": "1"}, 1500);
         $("#first").delay(1500).animate({"opacity": "0"}, 1500);
         $("#1").delay(4500).animate({"opacity": "1"}, 1500);
         $("#1").delay(1500).animate({"opacity": "0"}, 1500);

         $("#2").delay(4800).animate({"opacity": "1"}, 1500);
         $("#2").delay(1500).animate({"opacity": "0"}, 1500);

         $("#3").delay(5300).animate({"opacity": "1"}, 1500);
         $("#3").delay(1500).animate({"opacity": "0"}, 1500);

         $("#4").delay(5600).animate({"opacity": "1"}, 1500);
         $("#4").delay(1500).animate({"opacity": "0"}, 1500);

         $("#5").delay(5900).animate({"opacity": "1"}, 1500);
         $("#5").delay(1500).animate({"opacity": "0"}, 1500);
         licznik++;
         console.log(licznik);
         }
   }

$(document).ready(function(){

show_anim()


setInterval("show_anim()",12000);
});

Demo: http://jsfiddle.net/D5bxA/

Wojciech Parys
  • 339
  • 2
  • 18