jQuery / Methode / .delay() - Die nächste Aktion in einer Effektwarteschlange verzögern

jQuerys .delay() verzögert nachfolgende Aktionen in einer Warteschlange, üblicherweise der Effektwarteschlange. Es hält weder eine laufende Funktion noch JavaScript insgesamt an. Normale Methoden ohne diese Warteschlange können auch direkt hinter .delay() sofort ausgeführt werden.

Welche Aktionen warten tatsächlich?

Die .delay()-Dokumentation beschreibt .delay(duration, queueName). duration wird in Millisekunden angegeben; ohne queueName kommt eine Warteaktion in die Standardwarteschlange fx. Diese enthält nacheinander auszuführende Aktionen des jeweiligen Elements. Die Wartezeit beginnt erst nach vorheriger Arbeit, wenn die Verzögerung an der Reihe ist.

Nachfolgende Aktion Standard-Effektwarteschlange Bedeutung hinter .delay()
.fadeIn(), .fadeOut() Normalerweise verwendet Effekt startet nach der Wartezeit
.show(0) Als Effekt mit Dauer verwendet Sofortige Anzeige, sobald an der Reihe
.show(), .hide() Die sofortigen Formen ohne Argument verwenden sie nicht Können trotz Verkettung sofort laufen

.delay(800) fügt 800 Millisekunden Warten hinzu. "fast" und "slow" entsprechen 200 beziehungsweise 600 Millisekunden; Zahlen machen den Vergleich deutlicher. Eine vorherige Effektdauer ist davon getrennt: Auf einen Effekt von 200 Millisekunden folgt erst nach dessen Ende die zusätzliche Verzögerung von 800 Millisekunden.

Vollständiger Vergleich von show(0) und show()

Speichern Sie den gesamten Code in UTF-8 als delay-demo.html und öffnen Sie ihn im Browser. Zum Laden der offiziellen vollständigen jQuery-Datei vom Content Delivery Network (CDN) brauchen Sie Internet, aber keine Paketinstallation. Verwenden Sie nicht die schlanke slim-Ausgabe ohne Effekte.

Der Code lädt 4.0.0. Warten, sofortige Anzeige, weiterlaufendes JavaScript, Reset während des Wartens und Abbruch nativer Timer wurden mit 3.7.1 und 4.0.0 ausgeführt. Beide Kästen sind anfangs verborgen; die Anzeigebuttons steuern jeweils einen anderen Kasten.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Delay a queued effect, not JavaScript</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    .box { display: none; padding: 16px; margin: 12px 0; background: #e4f2ef; }
    button, select { padding: 8px; margin: 4px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Delay a queued effect, not JavaScript</h1>
  <label for="wait">Wait:</label>
  <select id="wait"><option value="800">800 ms</option><option value="200">200 ms</option></select>
  <button type="button" id="run">Queued show(0)</button>
  <button type="button" id="trap">Immediate show()</button>
  <button type="button" id="reset">Reset</button>
  <div class="box" id="queued">A queued display operation</div>
  <div class="box" id="plain">An immediate display operation</div>
  <p>Queue phase: <span id="phase">ready</span></p>
  <p id="continued"></p>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      const $queued = $("#queued");
      const $plain = $("#plain");
      let busy = false;
      function report() {
        const queued = $queued.is(":visible") ? "visible" : "hidden";
        const plain = $plain.is(":visible") ? "visible" : "hidden";
        $("#result").text(`queued=${queued} | plain=${plain}`);
      }
      $("#run").on("click", function () {
        if (busy) return;
        busy = true;
        $("#phase").text("waiting");
        $queued.stop(true, false).hide()
          .delay(Number($("#wait").val()))
          .show(0, function () {
            busy = false;
            $("#phase").text("done");
            report();
          });
        $("#continued").text("Script continues immediately");
        report();
      });
      $("#trap").on("click", function () {
        $plain.stop(true, false).hide()
          .delay(Number($("#wait").val())).show();
        report();
      });
      $("#reset").on("click", function () {
        $queued.add($plain).stop(true, false).hide();
        busy = false;
        $("#phase").text("ready");
        $("#continued").text("");
        report();
      });
      report();
    });
  </script>
</body>
</html>

Das Anfangsergebnis lautet:

queued=hidden | plain=hidden
  1. Lassen Sie Wait auf 800 ms und drücken Sie Queued show(0). Queue phase zeigt waiting, der erste Kasten bleibt verborgen.
  2. Script continues immediately erscheint sofort. .delay() blockiert das folgende JavaScript nicht.
  3. Nach dem Warten erscheint der erste Kasten; phase wird done und das Ergebnis queued=visible | plain=hidden.
  4. Drücken Sie Reset, dann Immediate show(). Der zweite Kasten erscheint ohne Warten, Ergebnis queued=hidden | plain=visible. .show() ohne Argument arbeitet außerhalb dieser Warteschlange.
  5. Setzen Sie erneut zurück, wählen Sie 200 ms und drücken Sie Queued show(0) für kürzeres Warten.
  6. Drücken Sie während einer 800-ms-Wartezeit Reset. Beide bleiben verborgen und phase wird ready. Auch nach Ablauf der ursprünglichen Zeit erscheint der erste Kasten nicht erneut.

Die Null in .show(0) ist die Dauer des Anzeigeeffekts, sobald er an der Reihe ist. Sie hebt die vorherige Wartezeit nicht auf. Sofortiges .show() und eingereihtes .show(0) sind daher unterschiedlich.

Warteschlangennamen und Reset verwalten

.queue() verwaltet die Arbeitswarteschlange eines Elements. Verwenden Sie für Verzögerung und Folgeaktion denselben eigenen Namen. Setzen Sie keinen automatischen Start voraus: Starten Sie eine eigene Warteschlange beispielsweise ausdrücklich mit .dequeue("work").

Reset verwendet .stop(true, false), um diese Effektwarteschlange zu leeren und ihren aktuellen Fortschritt anzuhalten. In beiden geprüften Versionen verhinderte Reset während des Wartens die spätere Anzeige. .delay() selbst liefert weder eine native Timer-ID noch einen unabhängigen Abbruchbezug und eignet sich nicht als allgemeiner Planungs- und Abbruchmechanismus für JavaScript.

.clearQueue() entfernt noch ausstehende Einträge. Künftige Arbeit zu entfernen und laufende Arbeit zu stoppen sind verschiedene Aufgaben. Das Beispiel setzt nur seine zwei Kästen zurück; busy ignoriert weitere Queued-show(0)-Anforderungen während des Laufs, damit sich Wartezeiten nicht ansammeln.

Für normale Funktionen abbrechbare Timer einsetzen

Für Aufgaben außerhalb einer Animationswarteschlange planen Sie eine Funktion mit setTimeout(). Speichern Sie die zurückgegebene ID und übergeben Sie sie bei Bedarf an clearTimeout(). Führen Sie diesen vollständigen Teilcode in der Entwicklerkonsole aus: Die nach 800 Millisekunden geplante Meldung later wird abgebrochen, nur cancelled erscheint.

const timer = setTimeout(() => console.log("later"), 800);
clearTimeout(timer);
console.log("cancelled");
cancelled

Timer- und Effektdauern garantieren keine exakte Ausführungszeit. Andere Browserarbeit und der Tabzustand können die Ausführung verzögern. Verknüpfen Sie wichtige Folgearbeit mit dem tatsächlichen Abschluss statt mit einer geschätzten festen Wartezeit.

Wartet eine Methode scheinbar nicht, prüfen Sie ihre Warteschlangennutzung sowie Element und Namen. Fehlt der Kasten ganz, kontrollieren Sie Auswahl und vorhandenes Ziel, den Start eigener Warteschlangen, die vollständige jQuery-Datei in Network und Fehler in Console.