40

If you select a class or collection of elements to animate with jQuery:

$('.myElems').animate({....});

And then also use the callback function, you end up with a lot of unneccessary animate() calls.

var i=1;
$('.myElems').animate({width:'200px'}, 200, function(){
    //do something else
    $('#someOtherElem').animate({opacity:'1'}, 300, function(){        
        if (i>1) console.log('the '+i+'-th waste of resources just finished wasting your resources');
        i++;
    });
});

Arguably this is just bad code and / or design - but is there something I can do that both avoids having many animate() calls with only one of them using the callback, and having a load of unneccessary callbacks executing and screwing with my code / expected behaviour?

Ideally I'd just be able to code a single 'disposable' callback that will only run once - otherwise perhaps there is an efficient way to test if something is already being animated by jQuery?

Example: http://jsfiddle.net/uzSE6/ (warning - this will show a load of alert boxes).

1
  • define a flag variable either on file scope or somewhere accessible by the animate(). check it before $("#someOtherElem').animate() call and set it in it's body so $("#someOtherElem').animate() won't be invoked next time.
    – fardjad
    Commented Jan 9, 2012 at 18:31

2 Answers 2

107

You could use when like:

$.when($('.myElems').animate({width: 200}, 200)).then(function () {
  console.log('foo');
});

http://jsfiddle.net/tyqZq/

Alternate version:

$('.myElems').animate({width: 200}, 200).promise().done(function () {
  console.log('foo');
});
2
  • 7
    I like this. I like this very much. I didn't know about these functions, this helped alot :) Commented Jan 10, 2012 at 9:04
  • 6
    +1 I found it quite useful for $('html, body').animate(...)
    – Alvaro
    Commented Oct 15, 2014 at 16:15
2

You can create a variable to block second+ callback...

var i=1;
$('.myElems').animate({width:'200px'}, 200, function(){
    //do something else
    $('#someOtherElem').animate({opacity:'1'}, 300, function(){        
        if (i>1) return;
        else
        {
            console.log('the '+i+'-th waste of resources just finished wasting your resources');
            i++;
        }
    });
});

This will only fire once as every subsequent callback will get canceled :)

2
  • 3
    I would suggest using a different variable name than i, which is common and likely to be accidentally overwritten, and setting it to true or false instead for clarity. Commented Jan 9, 2012 at 18:32
  • 1
    ^ Sure, but i used i as it was already available in the example code, i just used it slightly adjusted. From standpoints of clarity something like callbackdone set to boolean values would make much more sense.
    – bardiir
    Commented Jan 9, 2012 at 18:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.