Как добавить паузу между каждой итерацией jQuery .each()?

Я беру массив объектов jQuery, а затем через .each() изменяю каждый отдельный jquery в массиве.

В этом случае я обновил имена классов, чтобы активировать свойство -webkit-transition для использования перехода css.

Я бы хотел, чтобы перед каждым переходом css была пауза. Я использую следующее, но между каждым обновлением нет задержки. Вместо этого они все обновляются одновременно.

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

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

Я надеялся, что setTimeout решит эту проблему, но, похоже, это не работает. Есть ли способ сделать паузу перед каждым обновлением имени CLASS для каждого объекта?


person DA.    schedule 05.03.2011    source источник
comment
попробуйте использовать кавычки вокруг функции addPositioningClass, например: setTimeout('addPositioningClass($(this))', 500)   -  person amosrivera    schedule 05.03.2011
comment
не могли бы вы увеличить тайм-аут для каждой итерации, скажем, 500,1000,1500...   -  person Rob    schedule 05.03.2011


Ответы (8)


Я добавил это как комментарий, но теперь, когда я правильно его прочитал и ответил на свой вопрос, это, вероятно, сработает:

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

  var time = 500;

  $cards.each(function() {
      setTimeout( function(){ addPositioningClass($(this)); }, time)
      time += 500;
  });
}
person Rob    schedule 05.03.2011
comment
Чем ваш код отличается от OP? Произошла ошибка области действия, поскольку addPositioningClasses не существует в контексте setTimeout. - person JohnP; 05.03.2011
comment
@JohnP - @DA заявляет, что код работает, но все элементы позиционируются одновременно, я не знал, что область действия функции была частью проблемы... - person Rob; 05.03.2011
comment
Я только что попробовал это в скрипке, и это не работает. Я могу ошибаться, но я вообще не понимаю, как этот код может работать. - person JohnP; 05.03.2011
comment
@JohnP - @DA сказал --› Я использую следующее, но между обновлениями нет задержки. Вместо этого они все обновляются одновременно. - person Rob; 05.03.2011
comment
@DA, не могли бы вы уточнить, работает ли текущий setTimeout() или нет? @ Роб, я удалил свой -1 на всякий случай :) - person JohnP; 05.03.2011
comment
Это было решением! Разница в том, что я установил для всего тайм-аут 500. Поскольку они выполняются одновременно, между ними не было задержки. Увеличив время ожидания на 500 для каждого элемента, вы получите визуальную задержку. спасибо, Роб! - person DA.; 05.03.2011
comment
Решение: которое также присутствует в этом Git: gist.github.com/Zackio/7648481 - person Pranesh Janarthanan; 22.08.2018

Извините, что поднимаю старую тему, но этот совет может быть полезен для подобных проблем:

$cards.each(function(index) {
    $(this).delay(500*index).addClass('position');
});
person johnjohn    schedule 03.08.2012
comment
Имейте в виду, что delay предназначен только для очереди анимации и не будет работать, например. css() (см. здесь) - person Yan Foto; 20.01.2015
comment
Вы должны использовать .queue().dequeue()) при задержке .addClass(): $(this).delay(500*index).queue(function() { $(this).children('.flipcontainer').addClass('visible').dequeue(); }); - person aksu; 02.06.2015
comment
@aksu Вы должны скопировать то, что у вас есть, и превратить это в ответ, потому что он потерян среди комментариев, и ваш ответ помог мне заставить его работать правильно. - person adamj; 28.04.2017

Если вы создадите метод, который вызывает себя каждые 500 мс, это должно сработать. Следующий код должен работать.

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)
    }
}

Проверено на скрипте: http://jsfiddle.net/jomanlk/haGfU/

person JohnP    schedule 05.03.2011
comment
Мне нужно еще немного изучить .push(). Я не знал об этом! - person DA.; 05.03.2011

Как насчет .delay()?

or

function addPositioningClasses($card){
  setTimeout(function() { $card.addClass('position')}, 1000);
}
person diEcho    schedule 05.03.2011
comment
Меня это тоже всегда удивляло, но до сих пор я не нашел контекста, в котором можно было бы применить этот метод. - person Sandwich; 05.03.2011
comment
Насколько я могу судить, delay() применяется только к анимации jQuery. - person DA.; 05.03.2011

Если вы ориентируетесь только на Safari/iOS, в зависимости от того, насколько важно для вас контролировать точное время анимационных последовательностей, вам, возможно, следует избегать любых решений, связанных с тайм-аутами JS. Нет никакой гарантии, что анимация завершится одновременно с истечением времени ожидания, особенно на медленных процессорах или компьютерах, на которых в фоновом режиме происходит множество операций. Более поздние версии webkit (включая мобильное сафари) позволяют синхронизировать анимационные последовательности через @-webkit-keyframes. На Webkit.org есть хорошее введение. На самом деле это довольно легко реализовать.

person Andrew    schedule 05.03.2011
comment
Я действительно ориентируюсь только на iOS (это приложение). Я не определяю время последовательности анимации, а, скорее, время ожидания, пока не будет обновлено имя класса, что затем, в свою очередь, вызовет CSS-переход webkit. - person DA.; 05.03.2011

Попробуйте это:

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

Буду честен... В прошлом $(this).delay() плохо себя вел в одних случаях и работал безупречно в других. Однако обычно это происходило в сочетании с вызовами анимации jQuery, а не с манипулированием атрибутами DOM.

Имейте в виду, что .delay() работает не так, как setTimeout. Дополнительную информацию см. в документации jQuery .delay().

Насколько мне известно, $().each выполняется процедурно, поэтому следующая итерация вызова должна начинаться только после завершения предыдущей.

person lsuarez    schedule 05.03.2011
comment
Я могу ошибаться, но при чтении документации jquery кажется, что задержка предназначена только для задержки анимации jQuery. Я думаю, что вы также правы в последнем абзаце. Дело в том, что я не задерживал вызов функции, устанавливающей класс, а скорее задерживал момент, когда класс будет установлен. Таким образом, он применил задержку ко всем 30 элементам одновременно, и все они затем задержались на одинаковое количество времени. - person DA.; 05.03.2011

Проверьте это, сработало хорошо для меня! :)

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

Этот код добавит начальную задержку на 50 мс. Затем для каждого цикла через класс «.row» будет добавлена ​​дополнительная задержка в 200 мс. Это создаст хороший эффект отложенного показа для каждой строки.

$( 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;
    });
});
person LeeF    schedule 19.10.2015
comment
Будет лучше, если вы добавите какой-нибудь комментарий, а не просто разбросаете код. - person woot; 19.10.2015