jQuery, Aufruf eines Callbacks nur einmal nach mehreren Animationen

Lesezeit: 3 Minuten

Angenommen, ich habe mehrere Animationen gleichzeitig ausgeführt und möchte eine Funktion aufrufen, sobald alle fertig sind.

Mit nur einer Animation ist es einfach; Dafür gibt es einen Rückruf. Zum Beispiel :

$(".myclass").fadeOut(slow,mycallback);

Das Problem ist, wenn mein Selektor mehrere Artikel findet, wird der Rückruf für jeden von ihnen aufgerufen.

Eine Problemumgehung ist nicht allzu schwer; zum Beispiel :

<!DOCTYPE html>
<html>
<head>
  <title>Example</title>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
  <script type="text/javascript">
    $(document).ready(function() {
      var $mc=$(".myclass"),l=$mc.length;
      $mc.fadeOut("slow",function(){
        if (! --l) $("#target").append("<p>All done.</p>");
      });
    });
  </script>
  <style type="text/css">
  </style>
</head>
<body>
  <p class="myclass">Paragraph</p>
  <p class="myclass">Paragraph</p>
  <p class="myclass">Paragraph</p>
  <p class="myclass">Paragraph</p>
  <p class="myclass">Paragraph</p>
  <p class="myclass">Paragraph</p>
  <div id="target"></div>
</body>
</html>

Meine Frage ist: Gibt es einen besseren Weg, dies zu tun?

  • In den meisten Fällen verwende ich einen booleschen Wert anstelle eines Zählers (damit die Aktion am Ende der ersten Animation ausgeführt wird), aber ansonsten ist es dieselbe Methode. Gute Frage, ich interessiere mich für andere Möglichkeiten.

    – Tom Bartel

    12. März 2010 um 11:25 Uhr

  • In der Tat. Sie möchten auf alle warten, wenn beispielsweise nicht alle Ihre Animationen die gleiche Länge haben (nicht wie in meinem vereinfachten Beispiel), und Sie etwas erst tun möchten, nachdem sich die Dinge nicht mehr bewegen oder in Ihrem Browser ausgeblendet werden.

    – David v.

    12. März 2010 um 11:32 Uhr

Benutzer-Avatar
Kratz

Sehen Sie sich die Diskussion in diesem Thread an: jQuery $.animate() mehrere Elemente, aber nur einen Callback auslösen

Das .when()/.then() und die .promise().done(callback()); Funktionen bieten eine viel elegantere Lösung für das Problem, am Ende aller Animationen einen einzelnen Calllback aufzurufen.

  • Guter Anruf. In ähnlicher Weise wird die Warteschlange verwendet, um einen Rückruf auszulösen, nachdem das letzte Element fertig ist: elements.fadeOut(330).last().queue( function(){ } );

    – Tyler

    16. Mai 2012 um 20:01 Uhr

Sie können für alle denselben Callback ausführen, aber nur die ausführen if Klausel, wenn derzeit keine mehr animiert werden, wie folgt:

  $(".myclass").fadeOut("slow", function() {
    if ($(".myclass:animated").length === 0)
      $("#target").append("<p>All done.</p>");
  });

Dies prüft nur, ob noch welche über die animiert werden :animated Wähler. Wenn Sie viele verschiedene Dinge animieren, verwenden Sie dasselbe Konzept, fügen Sie einfach wie folgt zum Selektor hinzu:

$(".myclass:animated, .myClass2:animated")

Wenn Sie es an vielen Orten verwenden, würde ich diesen Rückruf zu einem machen onFinish Funktion oder etwas, um es aufzuräumen.

  • Schön, ich mag den definativen Aspekt davon.

    – Mark Schultheiss

    12. März 2010 um 12:40 Uhr

  • Bin auch auf dieses Problem gestoßen. Clevere Lösung.

    – Nathan Osmann

    13. März 2010 um 2:44 Uhr

  • Ich habe dies versucht, aber der :animated-Selektor scheint in dem Moment, in dem der Rückruf ausgelöst wird, nicht gelöscht worden zu sein. Das Hinzufügen von .not(this) vor .length lässt es funktionieren.

    – Graham Parks

    23. Juli 2010 um 11:29 Uhr

  • @grahamparks – Es wird nicht klar sein wenn Es gibt eine weitere Animation in der Warteschlange für das Element, denken Sie daran, dass dies nur der Rückruf für ist Dies Animation, ein anderer könnte danach kommen … dieses Skript wurde wirklich für den Kontext der Frage geschrieben 🙂

    – Nick Craver

    23. Juli 2010 um 11:45 Uhr

  • Nick: Andere Animationen sind nicht das Problem. In meinen Tests stimmt das Element immer noch mit *:animated überein, wenn sein eigener Callback aufgerufen wird. Länge ist also nie 0.

    – Graham Parks

    26. Juli 2010 um 13:58 Uhr

In meinem Fall muss ich definieren

if ($(".myclass:animated").length === 1)

1144940cookie-checkjQuery, Aufruf eines Callbacks nur einmal nach mehreren Animationen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy