2010-03-12 11 views
26

Digamos que tengo varias animaciones ejecutándose a la vez, y quiero llamar a una función una vez que todas hayan finalizado.jQuery, llamando a una devolución de llamada una sola vez después de múltiples animaciones

Con solo una animación, es fácil; hay una devolución de llamada para eso. Por ejemplo:

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

Problema es que si mi selector encuentra varios elementos, se llamará a la devolución de llamada para cada uno de ellos.

Una solución no es muy difícil; por ejemplo:

<!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> 

Mi pregunta es: ¿existe una forma mejor de hacerlo?

+0

En la mayoría de los casos, utilizo un valor booleano en lugar de un contador (por lo que la acción se realiza al final de la primera animación), pero de lo contrario es el mismo método. Buena pregunta, tengo curiosidad por otras formas. –

+0

De hecho. Desea esperar a todos ellos si, por ejemplo, todas sus animaciones no son de la misma longitud (no como en mi ejemplo simplista), y desea hacer algo solo después de que las cosas dejen de moverse o se desvanezcan en su navegador. –

Respuesta

29

Puede ejecutar la misma llamada de retorno para todos ellos, pero sólo ejecutar la cláusula de if si ninguno actualmente se está animando más, como esto:

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

Esto se comprueba si alguno todavía se están animados a través de la :animated selector. Si estaba animando un montón de cosas diferentes a continuación, utilizar el mismo concepto, sólo tiene que añadir al selector de la siguiente manera:

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

Si se está usando en muchos lugares, me gustaría hacer que una función de devolución de llamada onFinish o algo para ponerlo en orden.

+0

Bien, me gusta el aspecto definitivo de esto. –

+0

Me gusta esto también, +1 –

+0

Se metió en este problema también. Solución inteligente. –

3

En mi caso tengo que definir

if ($(".myclass:animated").length === 1) 
42

mirada a la discusión sobre este tema: jQuery $.animate() multiple elements but only fire callback once

El .when()/.then() y los .promise().done(callback()); funciones proporcionan una solución mucho más elegante al problema de llamar a un solo calllback al final de todas las animaciones.

+12

Esta debería ser la respuesta correcta. –

+1

Buena llamada. De forma similar, esto utiliza la cola para ejecutar una devolución de llamada después de que el último elemento haya finalizado aniamting: elements.fadeOut (330) .last(). Queue (function() {}); – Tyler

Cuestiones relacionadas