Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running jQuery animations serially

I have a group of fade out animations, after which I want to run a group of animation calls.

How can I make sure one is run after the other?

If I do this:

$(div1).fadeOut(600);
$(div2).fadeOut(600);
$(div3).fadeOut(600);

$(div4).animation({opacity:1},600);
$(div5).animation({opacity:1},600);
$(div6).animation({opacity:1},600);

The animations run in parallel.

The above code is just a simplification/abstraction of the problem. I can't group all the calls in one function, and in real life there is a variable number of elements, each managed by it's own class.

like image 680
Itay Moav -Malimovka Avatar asked Jul 16 '11 14:07

Itay Moav -Malimovka


Video Answer


2 Answers

You can use jQuery deferred objects:

var deferred = [
    new $.Deferred(),
    new $.Deferred(),
    new $.Deferred()
];

$(div1, div2, div3).each(function(i, elem) {
    $(elem).fadeOut(600, function() { deferred[i].resolve(); });
});

$.when(deferred[0], deferred[1], deferred[2]).done(function() {
    $(div4, div5, div6).each(function(i, elem) {
        $(elem).animation({ opacity : 1 }, 600);
    });
});

As @Felix pointed out in the comments, a cleaner syntax for the $.when would look like this:

$.when.apply(null, deferred).done(function() {
    $(div4, div5, div6).each(function(i, elem) {
        $(elem).animation({ opacity : 1 }, 600);
    });
});
like image 165
Stephen Avatar answered Sep 17 '22 23:09

Stephen


If you are using jQuery 1.6+, deferred.pipe() can simplify the code:

$.Deferred(function (dfr) {
  dfr
  .pipe(function () { return $(div1).fadeOut(600); })
  .pipe(function () { return $(div2).fadeOut(600); })
  .pipe(function () { return $(div3).fadeOut(600); })
}).resolve();

Ref: http://blog.darkthread.net/post-2011-08-03-deferred-pipe-animation.aspx

like image 45
Darkthread Avatar answered Sep 21 '22 23:09

Darkthread