2010-03-03 8 views
12

Bitte vergib mir, wenn dies offensichtlich ist.Wie schreibe ich eine Schleife in jQuery, die darauf wartet, dass jede Funktion beendet wird, bevor die Schleife fortgesetzt wird

Ich habe eine unbekannte Anzahl von Elementen auf einer Seite, die ich nacheinander durchlaufen muss und Sachen machen muss. Allerdings muss die Schleife angehalten werden, bis die für die Elemente verwendeten Funktionen abgeschlossen sind, und dann mit der nächsten Iteration fortfahren.

Ich versuchte dies in einer $ .each-Schleife, aber es befeuerte die Befehle weit zu schnell und fertig, ohne zu warten, bis sie abgeschlossen sind.

Irgendwelche Ideen?

$('elem').each(function(){ 
    $(this).fadeIn().wait(5000).fadeOut(); 
}); 

Das ist, was ich habe, sehr einfach. Ich habe die wait() Funktion von hier: jquery cookbook site.

Problem ist, die Schleife nicht warten - der eigentliche Befehl funktioniert wie beabsichtigt, es ist nur, dass sie alle auf einmal gehen.

Jede Hilfe geschätzt, danke.

EDIT: Nach dieser ausgeführt wird, kann ich möchte dann wieder die Schleife ausgeführt werden, so dass die Liste der elems wird

EDIT2 in/out wieder nacheinander eingeblendet werden: da bekommen haben die 1.4.2 jQuery lib, verwendete 1.3.2, daher die benutzerdefinierte wait() - Funktion. Jetzt benutze delay() wie von lobstrosity erwähnt. Verwaltet, um etwas zusammenzufassen, was ich von seiner Antwort brauche, danke Lobstros :).

Antwort

9

Zu allererst jQuery 1.4 die delay Funktion hinzugefügt, die ich davon ausgehen, ist das, was Ihre Implementierung für benutzerdefinierte Wartezeiten erledigt.

Mit Verzögerung können Sie die Funktionalität jedes Elements "warten" auf dem vorherigen Element fälschen, um zu beenden, indem Sie den ersten Parameter für jeden Rückruf als Multiplikator für eine erste Verzögerung verwenden. Wie folgt:

var duration = 5000; 

$('elem').each(function(n) { 
    $(this).delay(n * duration).fadeIn().delay(duration).fadeOut(); 
}); 

So wird das erste Element sofort fadeIn. Die zweite wird nach 5.000 ms ausgeblendet. Die dritte nach 10.000 ms und so weiter. Denken Sie daran, dass dies vorgetäuscht ist. Jedes Element wartet nicht wirklich auf das vorherige Element, um es zu beenden.

+0

aaaahh das ist ziemlich nah, danke. Und ich benutzte 1.3.2, habe gerade die neueste lib, danke, dass du darauf hinweist. Das einzige Problem mit diesem ist, dass ich, wenn ich einmal die Aktionen zu $ ​​('. Elem') mache, alles nochmal machen möchte. Ich werde die Frage bearbeiten, um dies zu widerlegen, sollte es erwähnt haben, danke. – alan

+0

Ich habe es noch nicht perfekt, aber das beantwortet meine Frage, vielen Dank. – alan

0

Sie müssen wahrscheinlich vor der ersten Funktion warten nennen:

$(this).wait().fadeIn().wait(5000).fadeOut(); 

Die andere Möglichkeit ist, den Rückruf zu verwenden.

$(this).wait().fadeIn('slow', function(){$(this).fadeOut('slow')}); 

Auf diese Weise wird die FadeOut nicht gestartet, bis die FadeIn abgeschlossen ist.

+0

Dank für die Antwort, aber die Reihenfolge der fadeIn und fadeOuts ist kein Problem, es ist die Tatsache, dass die .each Schleife jedem von ihnen innerhalb etwa 0,3 Sekunden ruft, und das alles macht gleichzeitig brauche ich die Schleife, um auf den Rückruf zu warten. – alan

3

Ihre Hauptschleife, die each() verwendet, wird ohne Verzögerung über Ihre Sammlung von Elementen ausgeführt. Sie müssen diese Elemente stattdessen in eine Warteschlange stellen.

Diese brauchen könnte zwicken (und könnte möglicherweise jQuery Warteschlangen verwenden?), Aber Rekursion zu demonstrieren, um die Warteschlange zu verarbeiten:

function animate(elems) { 
    var elem = elems.shift(); 
    $(elem).fadeIn().wait(5000).fadeOut(2000, function() { 
     if (elems.length) { 
      animate(elems); 
     } 
    }); 
} 

var elems = $('elem'); 
animate(elems); 
+0

Ich denke, eine unbekannte Anzahl von Elementen ist dafür gut, weil wir einfach das nächste Element aus dem Array verschieben(). Dies wird jedoch nur einmal ausgeführt und dann beendet. –

+0

Verschiebung scheint nicht auf jquery Objekt zu arbeiten, ich habe diesen Fehler: 'TypeError: 'undefined' ist keine Funktion (Bewertung 'elems.shift()')' – Matthieu

+0

Nur die Lösung gegründet: Verwenden Sie get(): ' var elems = $ ("elem"). get(); ' – Matthieu

0

Hier ist eine Demo meiner solution.

Was Sie brauchen, ist keine Schleife für die Verarbeitung. Was Sie wollen, ist die Anrufe zu verketten. Scheint so, als könnte es einen einfacheren Weg geben, aber hier ist eine brutale Methode. passieren

// Create a function that does the chaining. 
function fadeNext(x,y) { 
    return function() { x.fadeIn(100).delay(100).fadeOut(1000, (y?y.fadeNext:y)); }; 
} 

// Get all the elements to fade in reverse order. 
var elements = []; 
$('.f').each(function(i,e) {elements.unshift(e);}); 

// Iterate over the elements and configure a fadeNext for each. 
var next; 
for (var i in elements) { 
    var e = $(elements[i]); 
    e.fadeNext = fadeNext(e,next); 
    next = e; 
} 

// Start the fade. 
next.fadeNext(); 
+0

das ist eine gute Idee, vielen Dank für die Veröffentlichung. Dieser Code ist gut :) – alan