I'm trying to animate a set of elements simultaneously (almost, there's a small delay between each animation):
$('.block').each(function(i){
$(this).stop().delay(60 * i).animate({
'opacity': 1
}, {
duration: 250,
complete: mycallbackfunction // <- this fires the callback on each animation :(
});
});
How can I run a callback function after all animations have completed?
I'm trying to animate a set of elements simultaneously (almost, there's a small delay between each animation):
$('.block').each(function(i){
$(this).stop().delay(60 * i).animate({
'opacity': 1
}, {
duration: 250,
complete: mycallbackfunction // <- this fires the callback on each animation :(
});
});
How can I run a callback function after all animations have completed?
Share Improve this question asked Apr 28, 2011 at 18:38 AlexAlex 68k185 gold badges459 silver badges650 bronze badges 4- you can have each individual anim. increment a value, and if that value is = number of animations, then run the actual function – davidosomething Commented Apr 28, 2011 at 18:43
- 1 is there a reason you can't call mycallbackfunction after the entire $(".block").each statement? or am i misunderstanding your code? – Thomas Shields Commented Apr 28, 2011 at 18:44
- yes. If I do that, the function will be executed right away. I want to wait for the animations to finish, then execute it – Alex Commented Apr 28, 2011 at 18:45
- Have a separate callback for the last animation. – aviraldg Commented Apr 28, 2011 at 18:47
5 Answers
Reset to default 5Use a closure around a counter variable.
var $blocks = $('.block');
var count = $blocks.length;
$blocks.each(function(i){
$(this).stop().delay(60 * i).animate({
'opacity': 1
}, {
duration: 250,
complete: function() {
if (--count == 0) {
// All animations are done here!
mycallbackfunction();
}
}
});
});
Note the saving of the list of items into the $block variable to save a lookup.
Since jQuery 1.5, you can use $.when
[docs], which is a bit easier to write and understand:
var $blocks = $('.block');
$blocks.each(function(i){
$(this).stop().delay(60 * i).animate({
'opacity': 1
}, {
duration: 250
});
});
$.when($blocks).then(mycallbackfunction);
DEMO
Felix Kling's answer will fire the callback when there's no animation left to do. This makes the callback firing even if the animation is stopped via $el.stop()
and thus not completed to the end.
I found an method by Elf Sternberg using deferred objects which I implemented in this jsfiddle:
http://jsfiddle.net/8v6nZ/
var block = $('.block');
block.each(function(i){
$(this).stop().delay(60 * i).animate({
'opacity': 1
}, {
duration: 250,
complete: i== (block.length-1) ? myCallbackFunction : function(){}
});
});
$('.block').each(function(i){
$(this).stop().delay(60 * i).animate({
'opacity': 1
}, {
duration: 250,
complete: ((i == $('.block').length - 1) ? mycallbackfunction : null)
});
});