when remove for done attribute jquery each

remove - Invocar una función jQuery después de que.each() se haya completado



jquery when each is done (9)

Debe poner en cola el resto de su solicitud para que funcione.

var elems = $(parentSelect).nextAll(); var lastID = elems.length - 1; elems.each( function(i) { $(this).fadeOut(200, function() { $(this).remove(); if (i == lastID) { $j(this).queue("fx",function(){ doMyThing;}); } }); });

En jQuery, es posible invocar una devolución de llamada o desencadenar un evento después de que se haya completado una invocación de .each() (o de cualquier otro tipo de devolución de llamada iterativa).

Por ejemplo, me gustaría que este "desaparecer y eliminar" para completar

$(parentSelect).nextAll().fadeOut(200, function() { $(this).remove(); });

antes de hacer algunos cálculos e insertar nuevos elementos después de $(parentSelect) . Mis cálculos son incorrectos si los elementos existentes aún son visibles para jQuery y para dormir / retrasar una cantidad arbitraria de tiempo (200 para cada elemento) parece una solución frágil en el mejor de los casos.

Puedo .bind() fácilmente .bind() la lógica necesaria para una devolución de llamada de evento, pero no estoy seguro de cómo invocar limpiamente el .trigger() después de que la iteración anterior se haya completado . Obviamente, no puedo invocar el disparador dentro de la iteración ya que dispararía varias veces.

En el caso de $.each() , he considerado agregar algo al final del argumento de datos (que buscaría manualmente en el cuerpo de la iteración) pero odiaría ser forzado a eso, así que estaba esperando había otra forma elegante de controlar el flujo con respecto a las devoluciones de llamada iterativas.


Encontré muchas respuestas relacionadas con matrices pero no con un objeto json. Mi solución fue simplemente iterar a través del objeto una vez al incrementar un contador y luego al iterar a través del objeto para realizar su código puede incrementar un segundo contador. Luego simplemente compara los dos contadores y obtiene su solución. Sé que es un poco torpe, pero hasta ahora no he encontrado una solución más elegante. Este es mi código de ejemplo:

var flag1 = flag2 = 0; $.each( object, function ( i, v ) { flag1++; }); $.each( object, function ( ky, val ) { /* Your code here */ flag2++; }); if(flag1 === flag2) { your function to call at the end of the iteration }

Como dije, no es el más elegante, pero funciona y funciona bien y todavía no he encontrado una mejor solución.

Cheers, JP


Es probable que sea tarde, pero creo que este código funciona ...

$blocks.each(function(i, elm) { $(elm).fadeOut(200, function() { $(elm).remove(); }); }).promise().done( function(){ alert("All was done"); } );


JavaScript se ejecuta de forma síncrona, por lo que lo que coloque después de each() no se ejecutará hasta que each() se complete.

Considere la siguiente prueba:

var count = 0; var array = []; // populate an array with 1,000,000 entries for(var i = 0; i < 1000000; i++) { array.push(i); } // use each to iterate over the array, incrementing count each time $.each(array, function() { count++ }); // the alert won''t get called until the ''each'' is done // as evidenced by the value of count alert(count);

Cuando se invoca la alerta, el conteo será igual a 1000000 porque la alerta no se ejecutará hasta que each() finalice.


Me encuentro con el mismo problema y lo solucioné con una solución como el siguiente código:

var drfs = new Array(); var external = $.Deferred(); drfs.push(external.promise()); $(''itemSelector'').each( function() { //initialize the context for each cycle var t = this; // optional var internal = $.Deferred(); // after the previous deferred operation has been resolved drfs.pop().then( function() { // do stuff of the cycle, optionally using t as this var result; //boolean set by the stuff if ( result ) { internal.resolve(); } else { internal.reject(); } } drfs.push(internal.promise()); }); external.resolve("done"); $.when(drfs).then( function() { // after all each are resolved });

La solución resuelve el siguiente problema: sincronizar las operaciones asíncronas iniciadas en la iteración .each (), utilizando el objeto diferido.


Ok, esto podría ser un poco después del hecho, pero .promise () también debería lograr lo que buscas.

Documentación prometida

Un ejemplo de un proyecto en el que estoy trabajando:

$( ''.panel'' ) .fadeOut( ''slow'') .promise() .done( function() { $( ''#'' + target_panel ).fadeIn( ''slow'', function() {}); });

:)


Si está dispuesto a hacerlo en un par de pasos, esto podría funcionar. Sin embargo, depende de que las animaciones terminen en orden. No creo que deba ser un problema.

var elems = $(parentSelect).nextAll(); var lastID = elems.length - 1; elems.each( function(i) { $(this).fadeOut(200, function() { $(this).remove(); if (i == lastID) { doMyThing(); } }); });


Una alternativa a la respuesta de @ tv:

var elems = $(parentSelect).nextAll(), count = elems.length; elems.each( function(i) { $(this).fadeOut(200, function() { $(this).remove(); if (!--count) doMyThing(); }); });

Tenga en cuenta que .each() sí mismo es sincrónico : la instrucción que sigue a la llamada a .each() se ejecutará solo después de que se .each() llamada .each() . Sin embargo, las operaciones asincrónicas iniciadas en la iteración .each() continuarán por supuesto a su manera. Ese es el problema aquí: las llamadas a desvanecer los elementos son animaciones basadas en temporizador, y esas continúan a su propio ritmo.

La solución anterior, por lo tanto, realiza un seguimiento de cuántos elementos se están desvaneciendo. Cada llamada a .fadeOut() obtiene una devolución de llamada de finalización. Cuando la devolución de llamada advierte que se cuenta a través de todos los elementos originales involucrados, se puede tomar alguna medida subsiguiente con la confianza de que todo el desvanecimiento ha finalizado.

Esta es una respuesta de cuatro años (en este momento en 2014). Una forma moderna de hacer esto probablemente implicaría usar el mecanismo Deferido / Promesa, aunque lo anterior es simple y debería funcionar bien.


qué pasa

$(parentSelect).nextAll().fadeOut(200, function() { $(this).remove(); }).one(function(){ myfunction(); });