2011-03-07 9 views
22

Necesito una devolución de llamada para ejecutarla una vez que varios elementos han terminado de animar. Mi selector de jQuery es la siguiente:Jquery: posponga la devolución de llamada hasta que se completen varias animaciones

$('.buttons').fadeIn('fast',function() { 
    // my callback 
}); 

El problema con esto es que la clase botones coincide con un número de elementos, todos los cuales necesitan ser desvanecido antes de que se ejecute la devolución de llamada. Tal como está ahora, la devolución de llamada se ejecuta después de que cada elemento individual haya terminado de animar. Esta NO es la función deseada. Estoy buscando una solución elegante para que mi devolución de llamada se ejecute solo una vez que todos los elementos coincidentes hayan terminado de animar. Esta pregunta ha aparecido en algunos lugares, incluido SO, pero nunca ha habido una respuesta elegante (ni siquiera una respuesta definitiva en ese sentido; las soluciones que funcionan para una persona no funcionan en absoluto para otras).

+2

tal vez hacer una función each() y cada vez que se complete la animación para una elemento, incrementa un contador. Cuando el contador alcanza la cantidad de elementos que se están animando, ¿ejecuta su función de devolución de llamada? – benhowdle89

+0

Posible duplicado de http://stackoverflow.com/questions/2897249/when-animating-how-fire-the-callback-only-when-all-elements-are-done –

+0

@Chris, gracias, no lo había visto pregunta aún - ¡es perfecto! Además, muy similar a las respuestas de @Riley y @Ross 'a continuación. – Richard

Respuesta

5

Una alternativa a @ respuesta de Ross, que siempre dará lugar a la devolución de llamada en el último botón a desvanecerse en (que puede o no ser el último botón que se dijo para animar) podría ser:

var buttons = $(".buttons"); 
var numbuttons = buttons.length; 
var i = 0; 

buttons.fadeIn('fast', function() { 
    i++; 
    if(i == numbuttons) { 
     //do your callback stuff 
    } 
}); 
+1

Esto puede parecer fácil y funciona bien, pero una mejor manera de hacerlo es descrito en la respuesta de @Underworld a continuación. – aalaap

1
var $buttons = $('.buttons'); 

$buttons.each(function (index) { 
    if (index == $buttons.length - 1) { 
     $(this).fadeIn('fast',function() { 
      // my callback 
     }); 
    } else { 
     $(this).fadeIn('fast'); 
    } 
}); 

no probado, pero esto debería aplicarse a la devolución de llamada sólo el último botón.

0

El La idea detrás de mi solución es mantener un contador. Cada vez que finaliza una animación, simplemente incrementa este contador, así podrá ver cuando esté en el último botón. Recuerde volver a poner el contador en cero cuando todo haya terminado, porque es posible que desee repetir esto (ocultarlos de nuevo, y volver a mostrarlos).

var $buttons=$('.buttons'), 
    button_n=$buttons.length, 
    button_counter=0; 
$buttons.fadeIn('fast', function() { 
    if (button_counter==button_n-1) { 
     alert('It is all done!'); 
     button_counter=0; 
    } else { 
     button_counter++; 
    } 
}); 
0
onClickBtnEdit = function(){ 
    var $EditDel = $($btnEdit).add($btnDel); 
    var btns = $EditDel.size(); 

    $EditDel.fadeOut("def",function(){     
     btns--; 
     if(btns===0){ 
      $($btnSave).add($btnCancel).fadeIn("slow"); 
     } 
    }); 
}; 
80

jQuery introdujo un promise en la versión 1.6 y es mucho más elegante que la adición de contadores.

Ejemplo:

// Step 1: Make your animation 
$(".buttons").each(function() { 
    $(this).fadeIn("fast"); 
}); 

// Step 2: Attach a promise to be called once animation is complete 
$(".buttons").promise().done(function() { 
    // my callback 
}); 
+7

Esta debería ser la respuesta. –

+0

@JonathanArkell, creo que el mismo –

+0

¿Se llama a la función de devolución de llamada en done() para completar cada elemento en $ ('botones') o cuando están * todos * resueltos? – TimeEmit

14

Para recoger las animaciones de elementos no relacionados en una única devolución de llamada se puede hacer esto:

$.when(
    $someElement.animate(...).promise(), 
    $someOtherElement.animate(...).promise() 
).done(function() { 
    console.log("Both animations complete"); 
}); 
+0

Muy bonito, gracias. – Mahn

+4

También tenga en cuenta que puede recopilar estas promesas en una matriz y luego usar 'apply' con' when', como hice: '$ .when.apply ($, animationPromises) .done (function() {console.log (" hecho ";}});' – Mahn

+1

no hay necesidad de llamar '.promise' en los argumentos a' $ .when' - lo hace automáticamente. – Alnitak

Cuestiones relacionadas