jQuery / Méthode / .delay() - Retarder l’action suivante dans la file des effets

Dans jQuery, .delay() retarde les opérations suivantes d'une file, généralement celle des effets. Elle ne suspend ni une fonction déjà en cours ni JavaScript dans son ensemble. Une méthode qui n'utilise pas cette file peut s'exécuter immédiatement même après .delay() dans la chaîne.

Reconnaître les opérations qui attendent

La documentation de .delay() décrit .delay(duration, queueName). duration est en millisecondes ; sans queueName, l'attente est ajoutée à la file d'effets par défaut, fx. Une file contient les actions à exécuter successivement pour cet élément. L'attente commence quand les actions précédentes sont terminées et que le délai arrive en tête.

Opération suivante File des effets par défaut Après .delay()
.fadeIn(), .fadeOut() Normalement utilisée L'effet commence après l'attente
.show(0) Utilisée comme effet avec durée Affichage immédiat quand son tour arrive
.show(), .hide() Les formes immédiates sans argument ne l'utilisent pas Exécution immédiate possible malgré la chaîne

.delay(800) ajoute 800 millisecondes d'attente. "fast" et "slow" correspondent à 200 et 600 millisecondes ; les nombres rendent ici la comparaison plus claire. La durée précédente est distincte : un effet de 200 millisecondes se termine avant le début des 800 millisecondes supplémentaires.

Exemple complet : show(0) et show()

Enregistrez tout le code en UTF-8 dans delay-demo.html puis ouvrez-le dans un navigateur. Internet est nécessaire pour charger la version officielle complète de jQuery depuis le réseau de diffusion de contenu, CDN, sans installation de paquet. N'utilisez pas la version slim, dépourvue d'effets.

Le code charge 4.0.0. L'attente en file, l'affichage immédiat, la poursuite de JavaScript, Reset pendant l'attente et l'annulation du minuteur natif ont été exécutés avec 3.7.1 et 4.0.0. Les deux blocs sont initialement masqués ; chaque bouton d'affichage agit sur un bloc différent.

<!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>

Résultat initial :

queued=hidden | plain=hidden
  1. Laissez Wait sur 800 ms et appuyez sur Queued show(0). Queue phase indique waiting et le premier bloc reste masqué.
  2. Script continues immediately apparaît immédiatement : .delay() n'a pas bloqué le JavaScript suivant.
  3. Après l'attente, le premier bloc apparaît, phase devient done et le résultat queued=visible | plain=hidden.
  4. Appuyez sur Reset puis Immediate show(). Le second bloc apparaît sans attendre et le résultat devient queued=hidden | plain=visible. .show() sans argument agit hors de cette file.
  5. Réinitialisez encore, choisissez 200 ms et lancez Queued show(0) pour une attente plus courte.
  6. Pendant l'attente de 800 ms, appuyez sur Reset. Les deux blocs restent masqués et phase revient à ready. Le premier ne réapparaît pas après l'échéance initiale.

Le zéro de .show(0) est la durée de l'effet d'affichage une fois son tour arrivé, pas une annulation de l'attente précédente. .show() immédiat et .show(0) mis en file ne sont donc pas interchangeables.

Gérer noms de files et réinitialisation

.queue() gère les opérations en attente d'un élément. Pour une file personnalisée, utilisez le même nom pour le délai et la suite. Ne supposez pas qu'elle démarre automatiquement : lancez-la explicitement, par exemple avec .dequeue("work").

Reset utilise .stop(true, false) pour vider la file des effets de cet exemple et interrompre sa progression actuelle. Dans les deux versions testées, cela a empêché l'affichage prévu après une réinitialisation pendant l'attente. .delay() ne renvoie pas d'identifiant de minuteur natif ni de mécanisme indépendant d'annulation ; ne l'utilisez pas pour planifier et annuler tout travail JavaScript.

.clearQueue() supprime les entrées non encore exécutées. Retirer le travail futur diffère d'arrêter le travail en cours. Cet exemple ne réinitialise que ses deux blocs ; busy ignore les demandes Queued show(0) supplémentaires pendant l'exécution pour éviter l'accumulation des délais.

Utiliser un minuteur pour une fonction ordinaire

Pour une action indépendante d'une file d'animation, planifiez la fonction avec setTimeout(). Conservez l'identifiant renvoyé et passez-le à clearTimeout() pour annuler. Exécutez ce fragment complet dans la Console des outils de développement : later, prévu après 800 millisecondes, est annulé ; seul cancelled apparaît.

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

Les durées des minuteurs et des files d'effets ne garantissent pas une heure exacte d'exécution. L'activité du navigateur et l'état de l'onglet peuvent retarder l'action. Reliez une suite importante à la fin réelle plutôt qu'à une durée fixe supposée.

Si une méthode semble ne pas attendre, vérifiez qu'elle utilise une file et vise le même élément et le même nom de file. Si le bloc n'apparaît jamais, contrôlez sélection et cible existante, démarrage d'une file personnalisée, chargement de jQuery complet dans Network et erreurs dans Console.