Vollständiges Ausführen von jQuery-Animationen ohne Warteschlange

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Es ist ziemlich üblich, dass die .animate()-Funktion von jQuery durch ein mouseEnter- oder hover-Ereignis ausgelöst wird. Das ist alles gut und schön, aber es bedeutet, dass wir damit rechnen müssen, dass diese Ereignisse mehrmals ausgelöst werden. Wenn das Element mit dem angehängten Hover-Ereignis mehrmals überfahren wird, bedeutet dies, dass die Animation mehrmals ausgelöst wird, was normalerweise unerwünscht ist. Der übliche Weg, damit umzugehen, ist die Verwendung der .stop()-Funktion, wie zum Beispiel

$(this).stop().animate({ width: "200px" });

Das ist jedoch definitiv keine Allheilmittel-Lösung. Lassen Sie uns also erforschen.

Wir wissen bereits, dass die **Nicht**-Verwendung von .stop() problematisch ist, da sich dann die Animationen in der Warteschlange aufreihen und es bei mehreren schnellen Hovern etwas umständlich ist. Aber die Nicht-Verwendung von .stop() ist auch in gewisser Weise perfekt, da die mouseEnter-Animation und die mouseLeave-Animation vollständig und sequenziell ausgeführt werden. Es ist diese Geschmeidigkeit, die ich hier anstrebe, nur ohne die Warteschlange.

Die Verwendung von .stop() verhindert die Warteschlange, **aber sie verhindert auch, dass die Animationen einen vollständigen Zyklus durchlaufen.** Maus weg, die stop-Funktion wird ausgelöst und stoppt die Animation, die bei mouseEnter ausgelöst wurde, und beginnt die Animation, die alles zurücksetzt.

Das Erste, womit ich anfing zu experimentieren, war die Verwendung von .stop() nur vor der einen oder der anderen Animation, aber das hilft nicht viel. Die .stop()-Funktion hat auch einige Parameter, die Sie übergeben können, wobei der zweite angibt, ob die Animation erzwungen abgeschlossen werden soll. Wenn er auf true gesetzt ist, wird die Animation tatsächlich beendet, aber sie geschieht nicht sanft, sie ruckt zu ihrem Endzustand, was ich im Allgemeinen als unerwünscht empfinde.

Die Lösung liegt darin, **nicht** mit einer neuen Animation zu beginnen, bis der Zustand des Elements nicht mehr animiert wird. Auf diese Weise müssen Sie sich nicht einmal um Warteschlangen kümmern, da ohnehin nur eine Animation gleichzeitig laufen kann. Es gibt ein paar Möglichkeiten, dies zu erreichen, aber diese fand ich am saubersten

$("div").hover(function(){
    $(this).filter(':not(:animated)').animate({ width: "200px" });
}, function() {
    $(this).animate({ width: "100px" });
});

Auf dem Weg hierher gab es viele Ideen. Schauen Sie sich die unten stehende Demo an, um all die verschiedenen Optionen zu sehen, die ich durchgegangen bin, sowie eine zusätzliche Methode, die ebenfalls funktioniert.

Demo ansehen

UPDATE: Schauen Sie sich unbedingt Ralf Stoltz's noch bessere Lösung an.