8

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?

4
  • you can have each individual anim. increment a value, and if that value is = number of animations, then run the actual function 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? 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 Commented Apr 28, 2011 at 18:45
  • Have a separate callback for the last animation. Commented Apr 28, 2011 at 18:47

5 Answers 5

5

Use 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.

Sign up to request clarification or add additional context in comments.

6 Comments

just do the decrement in myCallbackFn()... but ya this is the only answer I see
In order to do the decrement in mycallbackfunction(), it needs to be defined in the same scope as count. The OP's example didn't show where mycallbackfunction() was defined.
thanks! this seems to work :D but you have a mistake: it should be if (count == 0) mycallbackfunction();
ps: do you know how can I decrement and check count at the same time?
You can do it like this: if (--count == 0) { ...}
|
4

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

1 Comment

That will trigger the callback even if the animations were stopped via .stop().
4

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/

Comments

1
   var block = $('.block');
   block.each(function(i){
   $(this).stop().delay(60 * i).animate({
     'opacity': 1
    }, {
      duration: 250,
      complete: i== (block.length-1) ? myCallbackFunction : function(){}
    });
   });

Comments

1
$('.block').each(function(i){
   $(this).stop().delay(60 * i).animate({
     'opacity': 1
   }, {
      duration: 250,
      complete: ((i == $('.block').length - 1) ? mycallbackfunction : null)
   });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.