How do I animate in jQuery without stacking callbacks?
html, jquery, jquery-animate, jquery-callback, jquery-ui
Solution
If you're using a recent version of jQuery, use the animation promises:
$('div1').fadeOut('slow').promise().pipe(function() {
return $('div2').fadeOut('slow');
}).pipe(function() {
return $('div3').animate({ top: 500 }, 1000 );
});
You can make it generic:
$.chain = function() {
var promise = $.Deferred().resolve().promise();
jQuery.each( arguments, function() {
promise = promise.pipe( this );
});
return promise;
};
var animations = $.chain(function() {
return $('div1').fadeOut('slow');
}, function() {
return $('div2').fadeOut('slow');
}, function() {
return $('div3').animate({ top: 500 }, 1000 );
});
$.when( animations ).done(function() {
// ALL ANIMATIONS HAVE BEEN DONE IN SEQUENCE
});
Still a lot of function closures but that's the very nature of Javascript. However, it's much more natural and a lot more flexible using Deferreds/Promises since you avoid callbacks "inception".
Problem
Let's say I have three divs, and I'd like each to animate once the previous one is done. Currently, I write this: ``` $('div1').fadeOut('slow', function() { $('div2').fadeOut('slow', function() { $('div3').fadeOut('slow'); }); }); ``` Which is ugly, but manageable. Now imagine I have 10 different animations that need to happen one after the other on different elements. Suddenly the code gets so clunky that it's extremely hard to manage... Here's pseudocode for what I'm looking to do: ``` $('div1').fadeOut('slow' { delay_next_function_until_done: true } ); $('div2').fadeOut('slow' { delay_next_function_until_done: true } ); $('div3').animate({ top: 500 }, 1000 ); ``` How do I achieve this?