Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery, calling a callback only once after multiple animations

Let's say that I have several animations running at once, and I want to call a function once all of them are finished.

With only one animation, it's easy; there's a callback for that. For example :

$(".myclass").fadeOut(slow,mycallback); 

Trouble is, if my selector finds several items, the callback will be called for each of them.

A workaround is not too hard; for example :

<!DOCTYPE html> <html> <head>   <title>Example</title>   <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>   <script type="text/javascript">     $(document).ready(function() {       var $mc=$(".myclass"),l=$mc.length;       $mc.fadeOut("slow",function(){         if (! --l) $("#target").append("<p>All done.</p>");       });     });   </script>   <style type="text/css">   </style> </head> <body>   <p class="myclass">Paragraph</p>   <p class="myclass">Paragraph</p>   <p class="myclass">Paragraph</p>   <p class="myclass">Paragraph</p>   <p class="myclass">Paragraph</p>   <p class="myclass">Paragraph</p>   <div id="target"></div> </body> </html> 

My question is : is there a better way to do this ?

like image 484
David V. Avatar asked Mar 12 '10 11:03

David V.


2 Answers

Look at the discussion on this thread: jQuery $.animate() multiple elements but only fire callback once

The .when()/.then() and the .promise().done(callback()); functions provide a much more elegant solution to the problem of calling a single calllback at the end of all animations.

like image 64
Scrat Avatar answered Sep 16 '22 14:09

Scrat


You can run the same callback for all of them, but only execute the if clause if none are currently being animated anymore, like this:

  $(".myclass").fadeOut("slow", function() {     if ($(".myclass:animated").length === 0)       $("#target").append("<p>All done.</p>");   }); 

This just checks if any are still being animated via the :animated selector. If you were animating lots of different things then use the same concept, just add to the selector like this:

$(".myclass:animated, .myClass2:animated") 

If you're using it in lots of places, I'd make that callback a onFinish function or something to tidy it up.

like image 29
Nick Craver Avatar answered Sep 17 '22 14:09

Nick Craver