Jak dodać pauzę między każdą iteracją jQuery .each ()?


81

Pobieram tablicę obiektów jQuery, a następnie poprzez .each () modyfikując każdy pojedynczy jQuery w tablicy.

W tym przypadku zaktualizowałem nazwy klas, aby wyzwolić właściwość -webkit-transit-property w celu wykorzystania przejścia CSS.

Chciałbym, aby przed rozpoczęciem każdego przejścia CSS była przerwa. Używam następujących, ale nie ma opóźnienia między każdą aktualizacją. Zamiast tego wszystkie wydają się aktualizować jednocześnie.

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

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

Miałem nadzieję, że setTimeout rozwiąże ten problem, ale wygląda na to, że nie działa. Czy istnieje sposób na wykonanie pauzy przed każdą aktualizacją nazwy KLASY każdego obiektu?


spróbuj użyć cudzysłowów wokół funkcji addPositioningClass, na przykład: setTimeout ('addPositioningClass ($ (this))', 500)
amosrivera

1
czy mógłbyś zwiększyć limit czasu dla każdej iteracji, powiedzmy 500,1000,1500 ...
Rob

Odpowiedzi:


96

Dodałem to jako komentarz, ale teraz, gdy przeczytałem to poprawnie i odpowiedziałem na własne pytanie, prawdopodobnie zadziała:

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

  var time = 500;

  $cards.each(function() {
      setTimeout( function(){ addPositioningClass($(this)); }, time)
      time += 500;
  });
}

1
Czym różni się Twój kod od OP? Wystąpił błąd zakresu, ponieważ addPositioningClassesnie istnieje w kontekściesetTimeout
JohnP

@JohnP - @DA stwierdza, że ​​kod działa, ale wszystkie elementy są ustawione na raz, nie byłem świadomy, że zakres funkcji był częścią problemu ...
Rob

1
Po prostu spróbowałem tego na skrzypcach i nie działa. Mogę się mylić, ale nie mam pojęcia, jak ten kod może w ogóle działać.
JohnP

2
@JohnP - powiedział @DA -> „Używam następujących elementów, ale między każdą aktualizacją nie ma opóźnienia. Zamiast tego wszystkie wydają się aktualizować jednocześnie”.
Rob

2
Rozwiązanie: które jest również obecne w tym Gicie
Pranesh Janarthanan

49

Przepraszamy, że odkopałem stary wątek, ale ta wskazówka może być przydatna w przypadku podobnych problemów:

$cards.each(function(index) {
    $(this).delay(500*index).addClass('position');
});

6
Uwaga, delayto jest przeznaczone tylko dla kolejki animacji i nie będzie działać np. css()(Patrz tutaj )
Yan Foto

20
Musisz użyć .queue()(i .dequeue()) podczas opóźnienia .addClass():$(this).delay(500*index).queue(function() { $(this).children('.flipcontainer').addClass('visible').dequeue(); });
aksu

1
@aksu Powinieneś skopiować to, co tam masz i uczynić z tego odpowiedź, ponieważ jest zagubiona w komentarzach, a Twoja odpowiedź pomogła mi sprawić, że działa poprawnie.
adamj

10

Jeśli stworzysz metodę, która wywołuje samą siebie co 500 ms, powinna to zrobić. Poniższy kod powinien działać.

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

Testowane na skrzypcach: http://jsfiddle.net/jomanlk/haGfU/


Muszę jeszcze więcej zbadać .push (). Nie byłem tego świadomy!
DA.

3

A co z .delay () ?

lub

function addPositioningClasses($card){
  setTimeout(function() { $card.addClass('position')}, 1000);
}

Zawsze się tym zastanawiam, ale do dziś nie znalazłem kontekstu, w którym można by zastosować tę metodę.
Sandwich

3
Z tego co wiem, delay () dotyczy tylko animacji jQuery.
DA.

1

Jeśli celujesz tylko w Safari / iOS, w zależności od tego, jak ważne jest dla ciebie kontrolowanie dokładnego czasu sekwencji animacji, być może powinieneś unikać każdego rozwiązania, które obejmuje limity czasu JS. Nie ma gwarancji, że animacja zakończy się w tym samym czasie, co opóźnienie, szczególnie na wolnych procesorach lub maszynach, na których w tle dzieje się dużo rzeczy. Późniejsze wersje zestawu webkit (w tym mobilne safari) umożliwiają tworzenie sekwencji animacji w czasie za pośrednictwem @-webkit-keyframes. Webkit.org ma do tego fajne wprowadzenie . W rzeczywistości jest to dość łatwe do wdrożenia.


W istocie celuję tylko w iOS (to aplikacja). Nie określam czasu sekwencji animacji, ale raczej określam czas, przez jaki mam czekać, aż zaktualizuję nazwę klasy, co z kolei wyzwala CSS przejścia do zestawu webkit.
DA.

1

Spróbuj:

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

Będę szczery ... W przeszłości zdarzało mi się, że $ (this) .delay () źle się zachowywało, aw innych działało bezbłędnie. Jednak było to zwykle w połączeniu z wywołaniami animacji jQuery, a nie manipulowaniem atrybutami DOM.

Należy pamiętać, że .delay () nie działa w taki sam sposób, jak setTimeout. Więcej informacji można znaleźć w dokumentacji jQuery .delay () .

O ile mi wiadomo, $ (). Każdy wykonuje proceduralnie, więc następna iteracja wywołania powinna rozpocząć się dopiero po zakończeniu poprzedniego.


Może się mylę, ale czytając dokumentację jQuery, wygląda na to, że opóźnienie służy tylko do opóźniania animacji jQuery. Myślę, że masz rację również w tym ostatnim akapicie. Chodziło o to, że nie opóźniałem wywołania funkcji ustawiającej klasę, ale raczej opóźniałem, kiedy klasa miała zostać ustawiona. Tak więc zastosował opóźnienie do wszystkich 30 elementów w tym samym czasie, a następnie wszystkie opóźniły ten sam czas.
DA.

0

Sprawdź to, działało dobrze dla mnie! :)

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

-2

Ten kod doda ustawienie opóźnienia początkowego na 50 ms. Następnie dla każdej pętli przechodzącej przez klasę „.row” doda dodatkowe 200 ms opóźnienia. Stworzy to ładny efekt opóźnionego pokazu dla każdego rzędu.

$( 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;
    });
});

6
Najlepiej, jeśli dodasz komentarz, a nie tylko wyrzucisz kod.
woot
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.