¿Cómo agregar una pausa entre cada iteración de jQuery .each ()?

81

Estoy tomando una matriz de objetos jQuery y luego a través de .each () modificando cada jquery individual en la matriz.

En este caso, actualicé los nombres de las clases para activar una propiedad -webkit-transition-property para utilizar una transición css.

Me gustaría que hubiera una pausa antes de que comience cada transición de CSS. Estoy usando lo siguiente, pero no hay demora entre cada actualización. En cambio, todos parecen actualizarse a la vez.

function positionCards() {
  $cards = $('#gameboard .card');
  $cards.each(function() {
      setTimeout( function(){ addPositioningClass($(this)); }, 500 )
  });
}

function addPositioningClasses($card){
  $card
    .addClass('position')
}

Esperaba que setTimeout resolviera esto, pero no parece estar funcionando. ¿Hay alguna forma de realizar la pausa antes de cada actualización del nombre de CLASE de cada objeto?

DA.
fuente
intente usar comillas alrededor de la función addPositioningClass, como esta: setTimeout ('addPositioningClass ($ (this))', 500)
amosrivera
1
¿Podría incrementar el tiempo de espera para cada iteración, digamos 500,1000,1500 ...
Rob

Respuestas:

96

Agregué esto como comentario, pero ahora que lo he leído correctamente y respondí mi propia pregunta, esto probablemente funcionaría:

function positionCards() {
  var $cards = $('#gameboard .card');

  var time = 500;

  $cards.each(function() {
      setTimeout( function(){ addPositioningClass($(this)); }, time)
      time += 500;
  });
}
Robar
fuente
1
¿En qué se diferencia su código del OP? Hay un error de alcance porque addPositioningClassesno existe en el contexto desetTimeout
JohnP
@JohnP - @DA afirma que el código funciona pero que todos los elementos están posicionados a la vez, no sabía que el alcance de la función era parte del problema ...
Rob
1
Lo intenté en un violín y no funciona. Puede que esté equivocado, pero no veo cómo ese código puede funcionar en absoluto.
JohnP
2
@JohnP - @DA dijo -> "Estoy usando lo siguiente, pero no hay demora entre cada actualización. En cambio, parece que todos se actualizan a la vez".
Rob
2
Solución: que también está presente en este Git: gist.github.com/Zackio/7648481
Pranesh Janarthanan
49

Perdón por desenterrar un hilo antiguo, pero este consejo podría ser útil para problemas similares:

$cards.each(function(index) {
    $(this).delay(500*index).addClass('position');
});
johnjohn
fuente
6
Tenga en cuenta que delayestá destinado solo para la cola de animación y no funcionará, por ejemplo, css()(ver aquí )
Yan Foto
20
Tienes que usar .queue()(y .dequeue()) al retrasar .addClass():$(this).delay(500*index).queue(function() { $(this).children('.flipcontainer').addClass('visible').dequeue(); });
aksu
1
@aksu Deberías copiar lo que tienes ahí y convertirlo en una respuesta, porque se pierde entre los comentarios y tu respuesta me ayudó a que funcione correctamente.
Adamj
10

Si crea un método que se llama a sí mismo cada 500 ms, debería hacer ese truco. El siguiente código debería funcionar.

var __OBJECTS = [];

$('#gameboard .card').each(function() {
    __OBJECTS.push($(this));
});

addPositioningClasses();

function addPositioningClasses() {
    var $card = __OBJECTS.pop();
    $card.addClass('position');
    if (__OBJECTS.length) {
        setTimeout(addPositioningClasses, 500)
    }
}

Probado en violín: http://jsfiddle.net/jomanlk/haGfU/

JohnP
fuente
Necesito investigar .push () un poco más. ¡No estaba consciente de eso!
DA.
3

¿Qué tal .delay () ?

o

function addPositioningClasses($card){
  setTimeout(function() { $card.addClass('position')}, 1000);
}
diEcho
fuente
Siempre me pregunto eso también, pero hasta el día de hoy no he encontrado un contexto donde se pueda aplicar este método.
Sandwich
3
Por lo que puedo decir, delay () solo se aplica a las animaciones jQuery.
DA.
1

Si solo está apuntando a Safari / iOS, dependiendo de lo importante que sea para usted controlar el tiempo exacto de las secuencias de animación, tal vez debería evitar cualquier solución que implique tiempos de espera de JS. No hay garantía de que la animación se complete al mismo tiempo que el tiempo de espera, particularmente en procesadores lentos o máquinas que tienen muchas cosas en segundo plano. Las versiones posteriores de webkit (incluido el safari móvil) permiten secuencias de animación cronometradas a través de @-webkit-keyframes. Webkit.org tiene una buena introducción . De hecho, es bastante fácil de implementar.

Andrés
fuente
De hecho, solo estoy apuntando a iOS (es una aplicación). No estoy cronometrando la secuencia de animación, sino más bien cronometrando cuánto tiempo esperar hasta actualizar el nombre de la clase, que luego, a su vez, desencadena una transición de webkit css.
DA.
1

Prueba esto:

function positionCards() {
  $('#gameboard .card').each(function() {
      $(this).delay(500).addClass('position');
  });
}

Seré honesto ... He tenido $ (this) .delay () se porta mal en el pasado en ciertos casos y funcionó perfectamente en otros. Sin embargo, esto era normalmente junto con las llamadas de animación de jQuery, no la manipulación de atributos DOM.

Tenga en cuenta que .delay () no funciona de la misma manera que setTimeout. Para obtener más información, consulte la documentación de jQuery .delay () .

Hasta donde yo sé, $ (). Cada uno se ejecuta procedimentalmente, por lo que la siguiente iteración de la llamada solo debe comenzar después de que se haya completado la anterior.

lsuarez
fuente
Puede que esté equivocado, pero al leer la documentación de jquery, parece que el retraso es solo para retrasar las animaciones de jQuery. Creo que también tiene razón en ese último párrafo. La cuestión era que no estaba retrasando la llamada a la función que configuraba la clase, sino que estaba retrasando el momento en que se configuraría la clase. Entonces, aplicó el retraso a los 30 elementos al mismo tiempo, y luego todos retrasaron la misma cantidad de tiempo.
DA.
0

Mira esto, ¡funcionó bien para mí! :)

jQuery('.optiresultsul li').each(function(index) {
    jQuery(this).delay(500*index).animate({ opacity: 1 }, 500,function(){
        jQuery(this).addClass('bgchecked');
    });
});
Deian Motov
fuente
-2

Este código agregará el retardo inicial a 50ms. Luego, para cada bucle a través de la clase ".row", agregará un retraso adicional de 200 ms. Esto creará un bonito efecto de espectáculo retardado para cada fila.

$( document ).ready(function() {
    // set inital delay
    var dtotal = 50;
    $(".row").each(function() {
    //add delay to function
      $(this).delay(dtotal).show();
    //add 200ms to delay for each loop
      dtotal = dtotal + 200;
    });
});
LeeF
fuente
6
Es mejor si agrega algunos comentarios y no solo arroja el código.
woot