JQuery: Waiting for Multiple Animations to Complete

Have you ever come across a situation where you wanted to execute a certain piece of code after an animation has completed running? This is a very common use-case in modern web development. jQuery team knows it, and that is why they accept a callback function as argument for every kind of animation call. In the example below, we pass in a callback function that will be executed after the “slideDown” animation is complete. This is the usual scenario.

$("#animateMe").slideDown(function() {
	// This piece of code will be executed 
	// after the animation is complete
});

But, in many other scenarios you might want to wait for multiple animations to complete before executing a certain piece of code. Lets assume that the two elements – “#element1” and “#element2” – are currently getting animated. Our goal is to execute a piece of code after both elements are finished with their respective animations. This is where it gets tricky. I was facing one such challenge today. The solution I have arrived at is to use the “:animated” pseudo-selector and “setInterval” to repeatedly check and wait until the animations have completed running. An example will clarify what I mean

var wait = setInterval(function() {
	if( !$("#element1, #element2").is(":animated") ) {
		clearInterval(wait);
		// This piece of code will be executed
		// after element1 and element2 is complete.
	}
}, 200);

In the example above, I use “setInterval” to repeatedly check if these two elements are NOT being “:animated”. If this condition is not met, then it means that atleast one of them is still getting animated. So, “setInterval” will check for the same condition again in 200 ms until the condition is met. If the condition is met, it means that the animations are complete. So, I immediately do a “clearInterval” and stop checking for this condition again. Any code written after this statement will get executed after both the animations are complete.

Ofcourse, the same code can be modified for more than two elements as well. Some more work, and we can make it handle any number of elements. But, I was wondering if there was an easier, better and more efficient approach to solve the same challenge. If fellow jquery lovers are aware of such solutions please feel free to leave a comment.

Ganeshji Marwaha

I spend my days as the Director of Technology for Mobility practice and help my clients design enterprise and consumer mobile strategies. Mobile Payments, Digital Wallet and Tokenization technologies are my areas of specialization

  • Pretty cool technique. Seemed a little innefficient but after trying out the callback version of this challenge, I think yours wins. 🙂

    Callback method:

    function allDone(){
    // This piece of code will be executed
    // after element1 and element2 is complete.
    }

    function callbackTrack(d){
    callbackTrack.queue = callbackTrack.queue || [false];
    if (d === ‘done’){
    if(callbackTrack.queue.shift() && callbackTrack.queue.length == 1) allDone();
    return;
    }
    callbackTrack.queue.push(true);
    return function(){ callbackTrack(‘done’); }
    }

    $(“#element1”).slideDown(500,callbackTrack());
    $(“#element2”).slideDown(700,callbackTrack());

  • Ganeshji Marwaha

    @Paul Irish – The technique you have posted looks nice too. I will give it a try.

  • Martin

    IT is one of the best and most leading technology in this modern era. There are many different ways to get high level posts in any famous organization. In order to get a good post in Information Technology, you must have detailed knowledge and experience about different topics like test king. I really appreciate the best and amazing efforts like that. Well done..

  • Ofcourse, the same code can be modified for more than two elements as well. Some more work, and we can make it handle any number of elements. thanks

  • Ofcourse, the same code can be modified for more than two elements as well. Some more work, and we can make it handle any number of elements. But, I was wondering if there was an easier, better and more efficient approach to solve the same challenge. If fellow jquery lovers are aware of such solutions please feel free to leave a comment.

  • AJAX and PHP is a great resource for PHP developers who want to expand their knowledge into front end web languages.But here I got some practical stuff!see…nobody so kind like you dude!Thanks for all information!

  • better and more efficient approach to solve the same challenge. If fellow jquery lovers are aware of such solutions please feel free to leave a comment.

  • Pingback: example animations()

  • If the condition is met, it means that the animations are complete.

  • An Ngo

    Here is a simple plugin to handle this problem using closure

    $.waitForNAnimations = function(numberOfAnimations,callback) {
    var count = 0;
    function cb() {
    count++;
    if ( count == numberOfAnimations) {
    count = 0;
    callback();
    }
    }
    return cb;
    }

    Usage: For each group of animations, define one callback function

    cb = $.waitForNAnimations(numberOfElements, function () {
    … call back code
    });

    Then
    $(“#element1”).slideDown(1000,cb);
    $(“#element2”).slideDown(2000,cb);

    Example

    Waiting for multiple animations
    <script src="/js/jquery-1.3.1.js" language="JavaScript"

    $.waitForNAnimations = function(numberOfAnimations,callback) {
    var count = 0;
    function cb() {
    count++;
    if ( count == numberOfAnimations) {
    count = 0;
    callback();
    }
    }
    return cb;
    }

    cb1 = $.waitForNAnimations(2, function () {
    alert(“Group 1 Done”);
    });

    function animate1() {
    if ($(“#elm1”).is(“:hidden”)) {
    $(“#elm1”).slideDown(2000,cb1);
    $(“#elm2”).slideDown(4000,cb1);
    } else {
    $(“#elm1”).hide();
    $(“#elm2”).hide();
    }
    }

    cb2 = $.waitForNAnimations(3, function () {
    alert(“Group 2 Done”);
    });

    function animate2() {
    if ($(“#elm3”).is(“:hidden”)) {
    $(“#elm3”).slideDown(2000,cb2);
    $(“#elm4”).slideDown(4000,cb2);
    $(“#elm5”).slideDown(6000,cb2);
    } else {
    $(“#elm3”).hide();
    $(“#elm4”).hide();
    $(“#elm5”).hide();
    }
    }

    div { background:#de9a44; margin:3px; width:80px;
    height:40px; display:none; float:left; }

  • $(“#elm2?).slideDown(4000,cb1); what ?

  • Just thought i’d comment and say neat design, did you code it yourself? Looksvery good.

  • Great! That worked perfect and don’t need a big block of code.

    Thanks, man!

  • I stumbled on this blog from delicious bookmark. Interesting topic with many great points. I wanted to say thank you for taking time to share this information. Michael from Michigan

  • Thanks for sharing

  • Thanks good article

  • Hi do you have code example for “tweets” menu mechanizam on the left.
    Thanks

  • Thanks for your sharing!grate!

  • Nice work,i am glad to see this page,it gives me the information what I need,thanks!

  • Loco

    Thank you! Exactly what I was looking for!

  • Those are some great inspirations. The last one is very clean. Thank,s for nice sharing.

  • Excellent

    By
    Parthiban
    http://www.phpjquery.com

  • Excellent

    By
    Parthiban
    PHP JQuery

  • Jonathan

    Sweet, I’m using this bit of code in an upcoming project of mine. Thanks much..

  • Hi,verybody,I will come again.

  • Hi. First of all I would like to say what a great site you have. I have been using it for a month or so now and really seeing the results. I am half an inch longer already and a good bit thicker. Thanx again.”

  • Quite a beautiful website. I recently built mine and i was looking for some ideas and your website gave me some. Did you develop the website alone?

  • Hey,this UI of your blog is nice and clean!Good work now,hope you providing more useful information!

  • Pingback: GET THE HOTTEST REVIEWS ON ALL OF THE LATEST GADGETS OUT!!()

  • Hi. I have a question.How to set start automatically. The use case is items is added carousel automatically and each time 1 items, the new item should be focused and display in the center of the carousel. Please, help me this action. Thank you so much.

  • ChrisH

    Thanks Ganesh!

    A elegant and simple solution that worked perfectly!

    🙂

  • I just discovered your website on yahoo and see that you’ve obtained some wonderful thoughts in this post. I particularly appreciate the way you’ve been capable to stick so really much believed small pellet mill into a relatively short submit (comparitively) which creates it an thoughtful post on your subject.

  • Fairly great blog post. the information that you shared is amazing and most notably I liked the way you shared things here. Extremely, the concept is real time applicable and as per the current demand of the internet user society.efox2011

  • From all the remarks in your articles, it appears such as this is often a very popular website. Keep up the truly amazing work.
    A thoughtful feeling may enslave a girl but staleness ever finger accepted by a get

  • I will definately post a link to this post on my website. I’m positive my followers will find this article really useful.

  • Pingback: IPAD 2 REVIEW()

  • nice post its helpful…
    http://www.raghibsuleman.com/

  • This is a really informative post. Thank you for sharing it with us.

  • I will definately post a link to this post on my website. I’m positive my followers will find this article really useful.

  • Great post!

  • Wow..great post.Looks like you got great interest. Well done!

  • This is a really informative post. Thank you for sharing it with us.

  • Mike

    You can do this with jQuery Deferreds much more simply. You can have multiple elements firing animations, and essentially bind 1 callback when they are all done animating. Below is a jsbin.com example, but here’s the basics of it:

    var callback = function(){
    alert(‘done!’);
    };

    var el1 = $(‘#element1’).slideUp(1000);
    var el2 = $(‘#element2’).slideUp(3000);

    $.when( el1, el2 ).done( callback );

    Link is here: http://jsbin.com/ozubu4/3/edit

  • Ganeshji Marwaha

    @mike – you are right. We can use the suggested technique starting version 1.5 onwards. But when this article was written, $.when wasn’t included in the then jquery release.

  • nice sharing article..thanks for the post

  • ??????????????????.?????????????????????.???????????????????????.?????????????????????????.?????????????????????????????????.????????????.??????????????????????????.

  • Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and I hope you post again soon.

  • I am in support of wonderland, this project is seeing very good fame and should be continued. I’m up for moral support and would do my part to promote this wonderful project.

  • I’ll be back soon on your site again so please continue sharing your great tips.

  • I am interesting in reading your blog and I like your take on the issue