Répétez les actions à un intervalle de temps javascript spécifié. Exemples de la fonction jQuery setTimeout()

Maison / Technologies

La méthode setInterval(), proposée sur les interfaces Window et Worker, appelle à plusieurs reprises une fonction ou exécute un extrait de code, avec un délai fixe entre chaque appel.

Il renvoie un ID d'intervalle qui identifie de manière unique l'intervalle, vous pouvez donc le supprimer ultérieurement en appelant clearInterval() . Cette méthode est définie par le mixin WindowOrWorkerGlobalScope. Syntaxe = var IDintervalle portée .setIntervalle(, fonction, [retard, arg1, ...]); Syntaxe = var IDintervalle portée arg2, fonction code ); Paramètres func Une fonction à exécuter toutes les millisecondes de retard. La fonction ne reçoit aucun argument et aucune valeur de retour n’est attendue. code Une syntaxe facultative vous permet d'inclure une chaîne au lieu d'une fonction, qui est compilée et exécutée toutes les millisecondes de délai. Cette syntaxe est .setIntervalle( non recommandé

pour les mêmes raisons qui font de l'utilisation de eval() un risque pour la sécurité. délai Le temps, en millisecondes (millièmes de seconde), pendant lequel le temporisateur doit s'écouler entre les exécutions de la fonction ou du code spécifié. Voir ci-dessous pour plus de détails sur la plage autorisée de valeurs de retard. arg1, ..., argN Facultatif Arguments supplémentaires transmis à la fonction spécifiée par

une fois la minuterie expirée.

Remarque : Passer des arguments supplémentaires à setInterval() dans la première syntaxe ne fonctionne pas dans

Internet Explorer

9 et antérieurs. Si vous souhaitez activer cette fonctionnalité sur ce navigateur, vous devez utiliser un polyfill (voir la section).

Valeur de retour

L'intervalID renvoyé est une valeur numérique non nulle qui identifie le minuteur créé par l'appel à setInterval() ; cette valeur peut être transmise pour annuler le délai d'attente.

Var intervalID = window.setInterval(myCallback, 500, "Paramètre 1", "Paramètre 2"); function myCallback(a, b) ( // Votre code ici // Les paramètres sont purement facultatifs. console.log(a); console.log(b); )

Exemple 2 : Alternance de deux couleurs

L'exemple suivant appelle la fonction flashtext() une fois par seconde jusqu'à ce que le bouton Stop soit enfoncé.

Exemple setInterval/clearInterval var nIntervId;

function changeColor() ( nIntervId = setInterval(flashText, 1000); ) function flashText() ( var oElem = document.getElementById("my_box"); oElem.style.color = oElem.style.color == "red" ? " blue" : "red"; // oElem.style.color == "red" ? "blue" : "red" est un opérateur ternaire. ) function stopTextColor() ( clearInterval(nIntervId); )

Bonjour le monde

Arrêt

Exemple 3 : simulation de machine à écrire

L'exemple suivant simule une machine à écrire en effaçant d'abord, puis en tapant lentement le contenu dans la NodeList qui correspond à un groupe spécifié de sélecteurs.< nPos) { return true; } var oRel, bExit = false; if (aMap.length === nPos) { aMap.push(0); } while (aMap < oSheet.parts.length) { oRel = oSheet.parts]; scroll(oRel, nPos + 1, bEraseAndStop) ? aMap++ : bExit = true; if (bEraseAndStop && (oRel.ref.nodeType - 1 | 1) === 3 && oRel.ref.nodeValue) { bExit = true; oCurrent = oRel.ref; sPart = oCurrent.nodeValue; oCurrent.nodeValue = ""; } oSheet.ref.appendChild(oRel.ref); if (bExit) { return false; } } aMap.length--; return true; } function typewrite () { if (sPart.length === 0 && scroll(aSheets, 0, true) && nIdx++ === aSheets.length - 1) { clean(); return; } oCurrent.nodeValue += sPart.charAt(0); sPart = sPart.slice(1); } function Sheet (oNode) { this.ref = oNode; if (!oNode.hasChildNodes()) { return; } this.parts = Array.prototype.slice.call(oNode.childNodes); for (var nChild = 0; nChild < this.parts.length; nChild++) { oNode.removeChild(this.parts); this.parts = new Sheet(this.parts); } } var nIntervId, oCurrent = null, bTyping = false, bStart = true, nIdx = 0, sPart = "", aSheets = , aMap = ; this.rate = nRate || 100; this.play = function () { if (bTyping) { return; } if (bStart) { var aItems = document.querySelectorAll(sSelector); if (aItems.length === 0) { return; } for (var nItem = 0; nItem < aItems.length; nItem++) { aSheets.push(new Sheet(aItems)); /* Uncomment the following line if you have previously hidden your elements via CSS: */ // aItems.style.visibility = "visible"; } bStart = false; } nIntervId = setInterval(typewrite, this.rate); bTyping = true; }; this.pause = function () { clearInterval(nIntervId); bTyping = false; }; this.terminate = function () { oCurrent.nodeValue += sPart; sPart = ""; for (nIdx; nIdx < aSheets.length; scroll(aSheets, 0, false)); clean(); }; } /* usage: */ var oTWExample1 = new Typewriter(/* elements: */ "#article, h1, #info, #copyleft", /* frame rate (optional): */ 15); /* default frame rate is 100: */ var oTWExample2 = new Typewriter("#controls"); /* you can also change the frame rate value modifying the "rate" property; for example: */ // oTWExample2.rate = 150; onload = function () { oTWExample1.play(); oTWExample2.play(); }; span.intLink, a, a:visited { cursor: pointer; color: #000000; text-decoration: underline; } #info { width: 180px; height: 150px; float: right; background-color: #eeeeff; padding: 4px; overflow: auto; font-size: 12px; margin: 4px; border-radius: 5px; /* visibility: hidden; */ }

Machine à écrire JavaScript - MDN Exemple de fonction Machine à écrire (sSelector, nRate) ( function clean () ( clearInterval(nIntervId); bTyping = false; bStart = true; oCurrent = null; aSheets.length = nIdx = 0; ) fonction scroll (oSheet, nPos , bEraseAndStop) ( if (!oSheet.hasOwnProperty("parts") || aMap.length

CopyLeft 2012 par le réseau de développeurs Mozilla

[ Jouer | Pause | Mettre fin]

Vivamus blandit massa ut metus mattis dans fringilla lectus imperdiet. Proin ac ante a felis ornare vehicula. Fusce pellentesque lacus vitae eros convallis ut mollis magna pellentesque. Placerat pellentesque enim à lacus ultricies vitae facilisis nisi fringilla. En tincidunt tincidunt tincidunt.

Machine à écrire JavaScript
Nullam commodo suscipit lacus non aliquet. Phasellus ac nisl lorem, sed facilisis ligula. Nam cursus lobortis placerat. Sed dui nisi, elementum eu sodales ac, placerat sit amet mauris. Pellentesque dapibus tellus ut ipsum aliquam eu auctor dui vehicula. Quisque ultrices laoreet erat, at ultrices tortor sodales non. Sed venenatis luctus magna, ultricies ultricies nunc fringilla eget. Praesent scelerisque urna vitae nibh tristique varius consequat neque luctus. Entier ornare, erat a porta tempus, velit justo fermentum elit, a fermentum metus nisi eu ipsum. Vivamus eget augue vel dui viverra adipiscing congue ut massa. Praesent vitae eros erat, pulvinar laoreet magna. Mécène vestibulum mollis nunc en posuere. Pellentesque sit amet metus a turpis lobortis tempor eu vel tortor. Cras sodales eleifend interdum.

Duis lobortis sapien quis nisl luctus porttitor. In tempor sempre libero, eu tincidunt dolor eleifend sit amet. Ut nec velit in dolor tincidunt rhoncus non non diam. Morbi auctor ornare orci, non euismod felis gravida nca. Curabitur elementum nisi a eros rutrum nec blandit diam placerat. Énéen tincidunt risus ut nisi consectetur cursus. Votre vie quam elit. Donec dignissim est in quam tempor consequat. Aliquam aliquam diam non felis convallis suscipit. Nulla facilisi. Donec lacus risus, dignissim et fringilla et, egestas vel eros. Duis malesuada accumsan dui, at fringilla mauris bibStartum quis. Cras adipiscing ultricies fermentum. Praesent bibStartum condimentum feugiat.

Nam faucibus, ligula eu fringilla pulvinar, lectus tellus iaculis nunc, vitae scelerisque metus leo non metus. Proin mattis lobortis lobortis. Quisque accumsan faucibus erat, vel varius tortor ultricies ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec libero nunc. Nullam tortor nunc, elementum a consectetur et, ultrices eu orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a nisl eu sem vehicula egestas.

Arguments de rappel

Comme indiqué précédemment, les versions 9 et antérieures d'Internet Explorer ne prennent pas en charge la transmission d'arguments à la fonction de rappel dans setTimeout() ou setInterval() . Le code suivant spécifique à IE illustre une méthode permettant de surmonter cette limitation. Pour l'utiliser, ajoutez simplement le code suivant en haut de votre script.

/*\ |*| |*| Polyfill spécifique à IE qui permet le passage d'arguments arbitraires au |*| fonctions de rappel des timers javascript (syntaxe standard HTML5)..setInterval |*| https://site/Utilisateur:fusionchess |*| |*| Syntaxe : |*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]); |*| var timeoutID = window.setTimeout(code, délai); |*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]); |*| var intervalID = window.setInterval(code, délai); |*| \*/ if (document.all && !window.setTimeout.isPolyfill) ( var __nativeST__ = window.setTimeout; window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var aArgs = Array .prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Function () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay ); ( var __nativeSI__ = window.setInterval; window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var aArgs = Array.prototype. slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Function () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay );

Une autre possibilité consiste à utiliser une fonction anonyme pour rappeler votre rappel, même si cette solution est un peu plus coûteuse. Exemple:

Var intervalID = setInterval(function() ( myFunc("un", "deux", "trois"); ), 1000);

var intervalID = setInterval(function(arg1) ().bind(undefined, 10), 1000);

Onglets inactifs Nécessite Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)

À partir de Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), les intervalles sont limités pour ne pas se déclencher plus d'une fois par seconde dans les onglets inactifs.

Le problème du "ceci"

Lorsque vous transmettez une méthode à setInterval() ou à toute autre fonction, elle est invoquée avec une valeur incorrecte. Ce problème est expliqué en détail dans la référence JavaScript.

Explication

MonTableau = ["zéro", "un", "deux"]; monArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); monArray.maMethod(); // affiche "zéro, un, deux" myArray.myMethod(1); // imprime "un" setTimeout(myArray.myMethod, 1000); // affiche "" après 1 seconde setTimeout(myArray.myMethod, 1500, "1"); // affiche "undefined" après 1,5 secondes // passer l'objet "this" avec .call ne fonctionnera pas // car cela changera la valeur de this dans setTimeout lui-même // alors que nous voulons changer la valeur de this dans myArray .myMethod // en fait, ce sera une erreur car le code setTimeout s'attend à ce que ce soit l'objet window : setTimeout.call(myArray, myArray.myMethod, 2000); // erreur : "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO : Opération illégale sur l'objet prototype WrappedNative" setTimeout.call(myArray, myArray.myMethod, 2500, 2 // même erreur);

Comme vous pouvez le voir, il n'existe aucun moyen de transmettre l'objet this à la fonction de rappel dans l'ancien JavaScript.

Une solution possible

Une façon possible de résoudre le problème "ceci" est de remplacer les deux fonctions globales natives setTimeout() ou setInterval() par deux non-autochtone ceux qui permettent leur invocation via la méthode Function.prototype.call. L'exemple suivant montre un remplacement possible :

// Active le passage de l'objet "this" via les timers JavaScript var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = fonction (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Function ? function () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay ); window.setInterval = fonction (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Function ? function () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay );

Ces deux remplacements permettent également le passage standard HTML5 d'arguments arbitraires aux fonctions de rappel des minuteries dans IE. Ils peuvent donc être utilisés comme non conforme aux normes les polyfills également. Voir le pour un conforme aux normes polyremplissage.

Test de nouvelles fonctionnalités :

MonTableau = ["zéro", "un", "deux"]; monArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); setTimeout(alerte, 1500, "Bonjour tout le monde !"); // l'utilisation standard de setTimeout et setInterval est conservée, mais... setTimeout.call(myArray, myArray.myMethod, 2000); // affiche "zéro, un, deux" après 2 secondes setTimeout.call(myArray, myArray.myMethod, 2500, 2); // affiche "deux" après 2,5 secondes

Pour une version plus complexe mais toujours modulaire ( Démon) voir Gestion des démons JavaScript . Cette version plus complexe n'est rien d'autre qu'un ensemble vaste et évolutif de méthodes pour le Démon constructeur. Cependant, le Démon le constructeur lui-même n'est rien d'autre qu'un clone de Mini-démon avec un support supplémentaire pour initialisation et au démarrage fonctions déclarées lors de l'instanciation du démon. Donc le Mini-démon framework reste la méthode recommandée pour les animations simples, car Démon sans sa collection de méthodes, il en est essentiellement un clone.

minidaemon.js /*\ |*| |*| :: MiniDémon:: |*| |*| Révision n°2 – 26 septembre 2014.setInterval |*| https://site/Utilisateur:fusionchess |*| https://github.com/madmurphy/minidaemon.js |*| |*| Ce framework est publié sous la licence publique générale limitée GNU, version 3 ou ultérieure. |*| http://www.gnu.org/licenses/lgpl-3.0.html |*| \*/ fonction MiniDaemon (oOwner, fTask, nRate, nLen) ( if (!(this && this instanceof MiniDaemon)) ( return; ) if (arguments.length< 2) { throw new TypeError("MiniDaemon - not enough arguments"); } if (oOwner) { this.owner = oOwner; } this.task = fTask; if (isFinite(nRate) && nRate >0) ( this.rate = Math.floor(nRate); ) if (nLen > 0) ( this.length = Math.floor(nLen); ) ) MiniDaemon.prototype.owner = null; MiniDaemon.prototype.task = null ; MiniDaemon.prototype.rate = 100 ; MiniDaemon.prototype.length = Infini ;< 1: this.INDEX + 1 >cette.longueur; ); MiniDaemon.prototype.synchronize = function () ( if (this.PAUSED) ( return; ) clearInterval(this.SESSION); this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this); ); MiniDaemon.prototype.pause = function () ( clearInterval(this.SESSION); this.PAUSED = true; ); MiniDaemon.prototype.start = function (bReverse) ( var bBackw = Boolean(bReverse); if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) ( return; ) this.BACKW = bBackw; this.PAUSED = false; this.synchronize();

MiniDaemon transmet des arguments à la fonction de rappel. Si vous souhaitez travailler dessus avec des navigateurs qui ne supportent pas nativement cette fonctionnalité, utilisez une des méthodes proposées ci-dessus.

Syntaxe

var monDaemon = nouveau MiniDaemon( cetObjet, rappel[ , taux [, longueur]]);

Description Notes d'utilisation

La fonction setInterval() est couramment utilisée pour définir un délai pour les fonctions exécutées encore et encore, telles que les animations. Vous pouvez annuler l'intervalle en utilisant WindowOrWorkerGlobalScope.clearInterval() .

Si vous souhaitez que votre fonction soit appelée une fois après le délai spécifié, utilisez .

Restrictions de retard

Il est possible que les intervalles soient imbriqués ; c'est-à-dire que le rappel de setInterval() peut à son tour appeler setInterval() pour démarrer un autre intervalle, même si le premier est toujours en cours. Pour atténuer l'impact potentiel que cela peut avoir sur performances, une fois que les intervalles sont imbriqués au-delà de cinq niveaux, le navigateur appliquera automatiquement une valeur minimale de 4 ms pour l'intervalle. Les tentatives de spécification d'une valeur inférieure à 4 ms dans les appels profondément imbriqués à setInterval() seront épinglées à 4 ms.

Les navigateurs peuvent imposer des valeurs minimales encore plus strictes pour l'intervalle dans certaines circonstances, même si celles-ci ne devraient pas être courantes. Notez également que le temps réel qui s'écoule entre les appels au rappel peut être plus long que le délai donné ; voir Raisons des retards plus longs que ceux spécifiés dans WindowOrWorkerGlobalScope.setTimeout() pour des exemples.

Assurez-vous que la durée d'exécution est plus courte que la fréquence des intervalles

S'il est possible que l'exécution de votre logique prenne plus de temps que l'intervalle de temps, il est recommandé d'appeler de manière récursive une fonction nommée à l'aide de setTimeout() . Par exemple, si vous utilisez setInterval() pour interroger un serveur distant toutes les 5 secondes, la latence du réseau, un serveur qui ne répond pas et une foule d'autres problèmes pourraient empêcher la requête de se terminer dans le temps imparti. En tant que tel, vous risquez de vous retrouver avec des requêtes XHR en file d'attente qui ne reviendront pas nécessairement dans l'ordre.

Dans la programmation dans les langages de script, il est périodiquement nécessaire de créer une pause - pour suspendre l'exécution du programme pendant un moment, puis continuer à travailler. Par exemple, dans les scripts VBS et PHP, les méthodes suivantes sont possibles :

VBS : wscript.sleep 1500 (arrêt pendant 1,5 seconde)

PHP : dormir (10 ); (arrêtez-vous pendant 10 secondes)

Pendant de telles pauses, le système d'exécution (PHP ou VBS) ne fait rien. Un développeur essayant d’utiliser intuitivement quelque chose de similaire en Javascript sera désagréablement surpris. Erreur courante lorsque vous essayez de créer une pause en Javascript, cela ressemble à ceci :

Fonction badtest() ( pour (var i=1; i< 10; i++) { window.setTimeout("document.getElementById("test1").value += " + i, 900) } }

Vous pensez que lorsque, pendant la boucle, vient le tour de dessiner le numéro suivant, votre setTimeout arrêtera honnêtement le Javascript de fonctionner, attendra 0,9 seconde, ajoutera le numéro souhaité à la fin du champ de saisie, puis continuera à travailler. Mais en réalité ce n'est pas le cas : setInterval et setTimeout en Javascript ne font que retarder l'exécution de l'action (ou de la fonction) spécifiée entre parenthèses. Dans notre exemple, ce qui suit se produira :

  • je = 1 ;
  • retarder l'ajout du chiffre « 1 » au champ de saisie de 0,9 seconde ;
  • Immédiatement après avoir posé ce problème, le cycle continue : i=2 ;
  • retarder l'ajout du chiffre « 2 » au champ de saisie de 0,9 seconde ;
  • Immédiatement signifie, par exemple, 1 ms (c'est-à-dire disproportionnellement petit par rapport à 900 ms) : la boucle fera son travail presque instantanément, créant plusieurs tâches différées à partir du même instant. Cela signifie que toutes les tâches de « dessin » en attente seront terminées presque en même temps, sans pause entre l'ajout de nouveaux nombres. Le cycle commence ; tout se fige pendant 0,9 s ; et shirr - tous les numéros sont tirés les uns après les autres.

    Comment appliquer correctement setTimeout dans un tel cas ? C'est compliqué. Vous devrez appeler la fonction récursivement(depuis l'intérieur de la fonction la même fonction), et pour que ce processus ne soit pas sans fin, définissez une condition d'arrêt (par exemple, la taille du nombre à imprimer) :

    Fonction welltest() ( si (je< 9) { document.getElementById("test2").value += ++i window.setTimeout("welltest()", 400) } }

    Et la variable i devra être initialisée en dehors de la fonction - par exemple, comme ceci :

    Maintenant, tout fonctionne comme il se doit (nous avons réduit le temps de retard de 0,9 s à 0,4 s). Mais pour de telles tâches, il est plus logique d'utiliser setInterval plutôt que setTimeout (même si cela nécessitera deux fonctions) :

    Fonction besttest() ( window.i = 0 window.timer1 = window.setInterval("draw()", 400) ) fonction draw() ( document.getElementById("test3").value += ++i if (i >= 9) clearInterval(window.timer1) )

    La particularité de la méthode Javascirpt setInterval est qu'elle ne passe pas « toute seule » ; elle doit être arrêtée avec une méthode spéciale clearInterval ; Et pour indiquer clairement quoi arrêter exactement, la tâche pour l'action différée se voit attribuer un identifiant spécial - un minuteur : window.timer1 = window.setInterval(...) .

    Des identifiants peuvent également être attribués à des tâches créées par la méthode setTimeout. Tous les ID de minuterie doivent être distincts les uns des autres (uniques dans la fenêtre actuelle du navigateur). Ensuite, vous pouvez créer plusieurs tâches différentes dans la fenêtre qui utilisent des actions différées, et ces tâches seront exécutées en parallèle (en quelque sorte simultanément, si l'ordinateur dispose de suffisamment de ressources), ce qui est fondamentalement impossible en PHP ou VBS.

    Voici un exemple de page avec plusieurs timers Javascript exécutés simultanément : setinterval.htm (fonctions Javascript dans le fichier setinterval.js). Tous les minuteurs de page (sauf le menu) peuvent être arrêtés à l'aide de la touche Échap. Tous les exemples de minuteries sont basés sur un compte à rebours « naturel » (et non abstrait i++) - temps ou distance. Toutes les « horloges » sont spécialement désynchronisées (pour plus de clarté). Des minuteries dépendant de la distance sont utilisées dans le menu « indicateur » et dans le menu déroulant (« pull-out »).

    Menu déroulant

    Notre menu coulissant est en fait coulissant (sous le « en-tête ») : des espaces sont spécialement laissés entre les éléments afin que vous puissiez voir comment il glisse. De manière inattendue, il s'est avéré que nous ne pouvions pas rendre la sortie aussi fluide pour des listes de différentes longueurs - probablement en raison des faibles performances de l'ordinateur (AMD Athlon 999 MHz).

    Il est bien évident que pour la beauté et l’harmonie, il est nécessaire que les listes des différents éléments du menu apparaissent en même temps. Autrement dit, les listes plus longues devraient disparaître avec plus grande vitesse, les plus courts - à une vitesse inférieure. Il semblerait que cela puisse être implémenté comme ceci :

  • Nous fixons par exemple le temps total de « départ » à 200 ms.
  • Si la liste déroulante a une hauteur de 20 px, il est évident que nous pouvons la déplacer vers le bas d'un pixel toutes les 10 ms d'intervalle - puis dans 200 ms, la liste entière apparaîtra.
  • Si la liste déroulante a une hauteur de 40 pixels, pour tenir dans le même laps de temps, nous devons la déplacer vers le bas d'un pixel toutes les 5 ms.
  • Selon cette logique, si la liste déroulante a une hauteur de 200 pixels, nous devrions la déplacer vers le bas d'un pixel toutes les 1 ms. Mais une telle vitesse ne fonctionne pas sur notre ordinateur - le navigateur n'a tout simplement pas le temps de dessiner la nouvelle position de la liste en une milliseconde. Oui. Javascript parvient à compter (qu'y a-t-il à compter ?), mais le navigateur (Firefox) n'a pas le temps d'afficher. Situation typique pour le web.

    Par conséquent, il est possible d'égaliser plus ou moins l'heure de départ du menu uniquement à l'aide de béquilles, et on ne sait toujours pas comment cela fonctionnera pendant plus longtemps. ordinateur rapide. Mais il faut compter sur le plus lent, non ? L'algorithme (sans tenir compte de la vitesse de l'ordinateur) donne quelque chose comme ceci :

  • Définissez le temps total de consultation de la liste : time = 224 (ms).
  • Nous fixons le temps minimum pour un intervalle du cycle : délai = 3 (ms).
  • Définissez le pas minimum pour déplacer la liste : offset = 1 (px).
  • On change tout cela en fonction de la hauteur de la liste : 1) augmenter le temps de retard (intervalle) en proportion inverse de la hauteur et directement proportionnelle au temps total (à une hauteur de 224 le coefficient est de 1) ; 2) si la hauteur est supérieure à 40 px, augmenter le pas minimum proportionnellement à la hauteur. La constante « 40 » a été obtenue expérimentalement pour l'ordinateur le plus lent. Les tests sur un ordinateur Pentium 4 CPU 2,53 GHz ont révélé exactement le même nombre - 40. Sinon, les minuteries se dérèglent, les listes ne sont pas en phase.
  • Maintenant, les listes sortent plus ou moins. Pour une durée plus ou moins similaire. Sur la page setinterval.htm.

    Et voici Bruce :

    Fonction slide_do(obj, maxtop, offset) (if (getTopLeft(obj).top< maxtop) { obj.style.top = getTopLeft(obj).top + offset } else { if (obj && obj.timer1) { clearInterval(obj.timer1) obj.timer1 = null } } }

    La fonction elle-même, qui fait sortir les listes imbriquées du menu, est, comme nous pouvons le voir, très simple. Il ne reste plus qu'à l'exécuter avec quelque chose comme cette ligne :

    Ts.timer1 = setInterval(function())(slide_do(ts, maxtop, offset)), delay)

    Eh bien, avant de commencer, calculez simplement tous ces maxtop et offset, et placez également la liste en position mintop. C’est ce que fait la fonction « préliminaire » slide() de 40 lignes. Et tous ensemble - dans le fichier setinterval.js. Oui, et cette merde ne fonctionnera pas du tout sans le fichier de styles inclus

    Il est extrêmement important de comprendre comment fonctionnent les minuteurs JavaScript. Souvent, leur comportement ne correspond pas à notre compréhension intuitive du multithreading, et cela est dû au fait qu'en réalité ils sont exécutés dans un seul thread. Examinons quatre fonctions avec lesquelles nous pouvons gérer les minuteries :

    • var id = setTimeout(fn, délai); - Crée une minuterie simple qui appellera une fonction donnée après un délai donné. La fonction renvoie un identifiant unique avec lequel le minuteur peut être mis en pause.
    • var id = setInterval(fn, délai); - Similaire à setTimeout, mais appelle continuellement la fonction à un intervalle donné (jusqu'à son arrêt).
    • clearInterval(id);, clearTimeout(id); - Accepte un ID de timer (renvoyé par l'une des fonctions décrites ci-dessus) et arrête l'exécution du callback"a.
    L’idée principale à considérer est que la précision de la temporisation n’est pas garantie. Pour commencer, le navigateur exécute tous les événements JavaScript asynchrones dans un seul thread (tels que les clics de souris ou les minuteries) et uniquement au moment où vient le tour de cet événement. Ceci est mieux démontré par le diagramme suivant :

    Cette figure contient de nombreuses informations à prendre en compte, mais sa compréhension vous permettra de mieux comprendre le fonctionnement de l'asynchronie JavaScript. Ce graphique représente le temps verticalement en millisecondes, les blocs bleus montrent les blocs de code JavaScript qui ont été exécutés. Par exemple, le premier bloc est exécuté en moyenne en 18 ms, un clic de souris bloque l'exécution pendant environ 11 ms, etc.

    JavaScript ne peut exécuter qu'un seul morceau de code (en raison de la nature de l'exécution à un seul thread), chacun bloquant l'exécution d'autres événements asynchrones. Cela signifie que lorsqu'un événement asynchrone se produit (comme un clic de souris, un appel de minuterie ou l'achèvement d'une requête XMLHttp), il est ajouté à une file d'attente et exécuté plus tard (l'implémentation varie selon le navigateur, bien sûr, mais acceptons appelez ça une "file d'attente").

    Pour commencer, imaginons que deux timers démarrent à l'intérieur d'un bloc JavaScript : setTimeout avec un délai de 10 ms et setInterval avec le même délai. Selon le moment où le timer démarre, il se déclenchera au moment où nous n'avons pas encore terminé le premier bloc de code. Notez cependant qu'il ne se déclenche pas immédiatement (cela n'est pas possible en raison d'un seul thread). Au lieu de cela, la fonction différée est mise en file d'attente et exécutée au prochain moment disponible.

    De plus, lors de l'exécution du premier bloc JavaScript, un clic de souris se produit. Le gestionnaire de cet événement asynchrone (et il est asynchrone car nous ne pouvons pas le prédire) ne peut pas être exécuté immédiatement à ce moment-là, il se retrouve donc également dans une file d'attente, comme le minuteur.

    Une fois le premier bloc de code JavaScript exécuté, le navigateur pose la question « Qu'est-ce qui attend d'être exécuté ? » DANS dans ce cas Le gestionnaire de clics de souris et le minuteur sont dans un état en attente. Le navigateur en sélectionne un (le gestionnaire de clics) et l'exécute. Le minuteur attendra la prochaine période de temps disponible dans la file d'attente d'exécution.

    Notez que pendant l'exécution du gestionnaire de clics de souris, le premier rappel d'intervalle se déclenche. Tout comme le rappel par minuterie, il sera mis en file d'attente. Cependant, notez que lorsque l'intervalle se déclenche à nouveau (pendant que le rappel du minuteur est en cours d'exécution), il sera supprimé de la file d'attente. Si tous les rappels d'intervalle étaient mis en file d'attente pendant l'exécution d'une grande partie du code, cela entraînerait un ensemble de fonctions en attente d'être appelées, sans aucun délai entre elles pour terminer leur exécution. Au lieu de cela, les navigateurs ont tendance à attendre qu'il n'y ait plus de fonctions. laissé dans la file d’attente avant d’en ajouter un autre à la file d’attente.

    Ainsi, nous pouvons observer le cas où le troisième déclenchement du rappel d'intervalle coïncide avec le moment où il est déjà exécuté. Cela illustre un point important : les intervalles ne se soucient pas de ce qui est en cours d'exécution, ils seront ajoutés à la file d'attente sans tenir compte du délai entre les exécutions.

    Enfin, une fois le deuxième rappel d'intervalle terminé, nous verrons qu'il ne reste plus rien à exécuter par le moteur JavaScript. Cela signifie que le navigateur attend à nouveau que de nouveaux événements asynchrones se produisent. Cela se produira au bout de 50 ms, où le rappel par intervalle fonctionnera à nouveau. À ce stade, rien ne pourra le bloquer, donc cela fonctionnera immédiatement.

    Regardons un exemple qui illustre bien la différence entre setTimeout et setInterval.
    setTimeout(function())( /* Un long bloc de code... */ setTimeout(arguments.callee, 10); ), 10);
    setInterval(function())( /* Un long bloc de code... */ ), 10);

    Ces deux options sont équivalentes à première vue, mais en réalité elles ne le sont pas. Le code utilisant setTimeout aura toujours un délai d'au moins 10 ms après l'appel précédent (cela peut être plus, mais jamais moins), tandis que le code utilisant setInterval aura tendance à être appelé toutes les 10 ms, quel que soit le moment où l'appel précédent a eu lieu.
    Résumons tout ce qui a été dit ci-dessus :
    - Les fonctions setTimeout et setInterval sont exécutées fondamentalement différemment en code asynchrone,
    - Si le timer ne peut pas être exécuté dans à l'heure actuelle, il sera retardé jusqu'au prochain point d'exécution (qui sera plus long que le délai souhaité),
    - Les intervalles (setInterval) peuvent être exécutés les uns après les autres sans délai si leur exécution prend plus de temps que le délai spécifié.

    Tout cela est extrêmement informations importantes pour le développement. Connaître le fonctionnement du moteur JavaScript, en particulier avec de nombreux événements asynchrones (ce qui arrive souvent), constitue une base solide pour créer des applications avancées.

    Source : http://learn.javascript.ru/settimeout-setinterval

    Presque toutes les implémentations de JavaScript disposent d'un planificateur de minuterie interne qui vous permet de planifier l'appel d'une fonction après une période de temps spécifiée.

    Cette fonctionnalité est notamment prise en charge dans les navigateurs et dans le serveur Node.JS.

    setTimeout

    Syntaxe:

    var timerId = setTimeout(func/code, delay[, arg1, arg2...])

    Paramètres :

    • fonction/code
      • Une fonction ou une ligne de code à exécuter.
      • La chaîne est conservée pour des raisons de compatibilité et n'est pas recommandée.
    • fonction
      • Latence en millisecondes, 1 000 millisecondes équivaut à 1 seconde.
    • arg1, arg2…
      • Arguments à transmettre à la fonction. Non pris en charge dans IE9-.
      • La fonction sera exécutée après le temps spécifié dans le paramètre delay.

    Par exemple, le code suivant déclenchera alert("Hello") après une seconde :

    function func () ( alert("Bonjour" ); ) setTimeout(func, 1000 );

    Si le premier argument est une chaîne, alors l'interpréteur crée une fonction anonyme à partir de cette chaîne.

    Autrement dit, cette entrée fonctionne exactement de la même manière :

    SetTimeout("alert("Bonjour")" , 1000 );

    Utilisez plutôt des fonctions anonymes :

    SetTimeout(function () ( alert("Bonjour" ) ), 1000 );

    Paramètres de fonction et de contexte

    En tout navigateurs modernesÉtant donné IE10, setTimeout vous permet de spécifier les paramètres de la fonction.

    L'exemple ci-dessous affichera "Bonjour, je m'appelle Vasya" partout sauf dans IE9- :

    function sayHi (who) ( alert("Bonjour, je suis " + who); ) setTimeout(sayHi, 1000 , "Vasya" );

    ...Cependant, dans la plupart des cas, nous avons besoin du support de l'ancien IE, et celui-ci ne vous permet pas de spécifier des arguments. Par conséquent, afin de les transférer, ils enveloppent l’appel dans une fonction anonyme :

    function sayHi (who) ( alert("Salut, je suis " + who); ) setTimeout(function () ( sayHi("Vasya") ), 1000 );

    L’appel de setTimeout ne transmet pas ce contexte.

    En particulier, appeler une méthode objet via setTimeout fonctionnera dans le contexte global. Cela peut conduire à des résultats incorrects.

    Par exemple, appelons user.sayHi() après une seconde :

    function Utilisateur (id) function () ( alert(this .id); ); ) var utilisateur = nouvel utilisateur (12345); setTimeout(user.sayHi, 1000 ); // attendu 12345, mais affichera "indéfini"

    Puisque setTimeout exécutera la fonction user.sayHi dans le contexte global, il n'aura pas accès à l'objet via this .

    En d’autres termes, ces deux appels à setTimeout font la même chose :

    // (1) une ligne setTimeout(user.sayHi, 1000 ); // (2) la même chose en deux lignes var func = user.sayHi; setTimeout(func, 1000 );

    Heureusement, ce problème est également facilement résolu en créant une fonction intermédiaire :

    function Utilisateur (id) ( this .id = id; this .sayHi = function () ( alert(this .id); ); ) var user = new User (12345); setTimeout(function () ( user.sayHi(); ), 1000 );

    Une fonction wrapper est utilisée pour transmettre des arguments entre navigateurs et préserver le contexte d'exécution.

    Annulation de l'exécution

    La fonction setTimeout renvoie un timerId qui peut être utilisé pour annuler l'action.

    Syntaxe:

    ClearTimeout (timerId)

    Dans l'exemple suivant, nous définissons un délai d'attente, puis supprimons (nous avons changé d'avis). Résultat, rien ne se passe.

    var timerId = setTimeout(function () ( alert(1) ), 1000 ); clearTimeout(timerId); définirIntervalle

    La méthode setInterval a une syntaxe similaire à setTimeout.

    var timerId = setInterval(func/code, delay[, arg1, arg2...])

    Le sens des arguments est le même. Mais contrairement à setTimeout , il n'exécute pas la fonction une seule fois, mais la répète régulièrement à un intervalle de temps spécifié. Vous pouvez arrêter l'exécution en appelant :

    ClearInterval (timerId)

    L'exemple suivant, une fois exécuté, affichera un message toutes les deux secondes jusqu'à ce que vous cliquiez sur le bouton Arrêter :

    var je = 1 ;

    var timer = setInterval(function () ( alert(i++) ), 2000 );

    Mise en file d'attente et superposition des appels dans setInterval

    L'appel setInterval(function, delay) provoque l'exécution de la fonction à l'intervalle de temps spécifié. Mais il y a ici une subtilité.

    En fait, la pause entre les appels est inférieure à l'intervalle spécifié.

    Autrement dit, le navigateur lance le lancement de la fonction proprement toutes les 100 ms, sans tenir compte du temps d'exécution de la fonction elle-même.

    Il arrive que l'exécution d'une fonction prenne plus de temps que le délai. Par exemple, la fonction est complexe, mais le délai est faible. Ou la fonction contient des instructions d'alerte/confirmation/invite qui bloquent le thread d'exécution. C’est là que les choses commencent à devenir intéressantes.

    Si une fonction ne peut pas être lancée parce que le navigateur est occupé, elle sera mise en file d'attente et exécutée dès que le navigateur sera libre.

    L'image ci-dessous illustre ce qui se passe pour une fonction dont l'exécution est longue.

    L'appel de fonction initié par setInterval est ajouté à la file d'attente et se produit immédiatement lorsque cela est possible :

    Le deuxième lancement de la fonction intervient immédiatement après la fin du premier :

    L'exécution n'est pas mise en file d'attente plus d'une fois.

    Si l'exécution d'une fonction prend plus de temps que plusieurs exécutions planifiées, elle sera toujours mise en file d'attente une fois. Il n’y a donc pas « d’accumulation » de lancements.

    Dans l'image ci-dessous, setInterval tente d'exécuter la fonction en 200 ms et met l'appel en file d'attente. À 300 ms et 400 ms, le minuteur se réveille à nouveau, mais rien ne se passe.

    L’appel de setInterval(function, delay) ne garantit pas le délai réel entre les exécutions.

    Il existe des cas où le délai réel est supérieur ou inférieur à celui spécifié. En général, ce n’est pas un fait qu’il y aura au moins un certain retard.

    Répétition de setTimeout imbriqué

    Dans les cas où non seulement une répétition régulière est nécessaire, mais un délai entre les exécutions est requis, setTimeout est utilisé pour réinitialiser chaque fois que la fonction est exécutée.

    Vous trouverez ci-dessous un exemple qui émet une alerte avec un intervalle de 2 secondes entre elles.

    var je = 1 ;

    var timer = setTimeout(function run () ( alert(i++); timer = setTimeout(run, 2000); ), 2000 );

    Le calendrier d'exécution aura des délais fixes entre les exécutions. Illustration pour un délai de 100 ms :

    Délai minimum

    Le minuteur du navigateur a la latence la plus faible possible. Cela varie d'environ zéro à 4 ms dans les navigateurs modernes. Chez les plus anciens, cela peut être plus long et atteindre 15 ms.

    Selon la norme, le délai minimum est de 4 ms. Il n'y a donc aucune différence entre setTimeout(..,1) et setTimeout(..,4) .

  • Le comportement sans latence de setTimeout et setInterval est spécifique au navigateur.
  • Dans Internet Explorer, le délai zéro setInterval(.., 0) ne fonctionnera pas. Cela s'applique spécifiquement à setInterval , c'est-à-dire setTimeout(.., 0) fonctionne bien.
  • Fréquence de déclenchement réelle

    Les déclenchements peuvent être beaucoup moins fréquents. Dans certains cas, le délai peut ne pas être de 4 ms, mais de 30 ms, voire 1 000 ms.

    La plupart des navigateurs (principalement ceux de bureau) continuent d'exécuter setTimeout / setInterval même si l'onglet est inactif. Dans le même temps, un certain nombre d'entre eux (Chrome, FF, IE10) réduisent la fréquence minimale du timer à 1 fois par seconde. Il s'avère que la minuterie fonctionnera dans l'onglet « arrière-plan », mais rarement.

    Lorsqu'ils fonctionnent sur batterie, sur un ordinateur portable, les navigateurs peuvent également réduire la fréquence pour exécuter du code moins souvent et économiser la batterie. IE est particulièrement célèbre pour cela. La réduction peut atteindre plusieurs fois, selon les paramètres. Si la charge du processeur est trop élevée, JavaScript risque de ne pas être en mesure de traiter les minuteries en temps opportun. Cela ignorera certaines exécutions de setInterval.

    Conclusion : une fréquence de 4 ms mérite qu'on s'y attarde, mais il ne faut pas compter dessus.

    Afficher les intervalles sur la console Le code qui compte les intervalles de temps entre les appels ressemble à ceci :

    var timeMark = nouvelle date ; setTimeout(function go () ( var diff = new Date - timeMark; // affiche le prochain délai sur la console au lieu de la page console .log(diff); // mémorise l'heure à la toute fin, // pour mesurer le délai entre les appels timeMark = new Date ; setTimeout(go, 100 ), 100 ); L'astuce est setTimeout(func, 0)

    Cette astuce mérite d’entrer dans les annales des hacks JavaScript.

    La fonction est enveloppée dans setTimeout(func, 0) si vous souhaitez l'exécuter après la fin du script en cours.

    Le fait est que setTimeout n'exécute jamais la fonction immédiatement. Il planifie seulement sa mise en œuvre. Mais l'interpréteur JavaScript ne commencera à exécuter les fonctions prévues qu'après l'exécution du script en cours.

    Selon la norme, setTimeout ne peut de toute façon pas exécuter une fonction avec un délai de 0. Comme nous l'avons dit précédemment, le délai sera généralement de 4 ms. Mais l'essentiel ici est que l'exécution aura lieu dans tous les cas après l'exécution du code actuel.

    Par exemple:

    résultat var ; fonction showResult () ( alert(result); ) setTimeout(showResult, 0 ); résultat = 2 *2 ; // affichera 4 Total

    Les méthodes setInterval(func, delay) et setTimeout(func, delay) vous permettent d'exécuter func régulièrement/une fois toutes les millisecondes de délai.

    Les deux méthodes renvoient l’ID du minuteur. Il est utilisé pour arrêter l'exécution en appelant clearInterval / clearTimeout .

    | | setIntervalle | setTimeout | || ----------- | ---------- | | Calendrier | L'appel est strictement programmé. Si l'interprète est occupé, un appel est mis en file d'attente. Le temps d'exécution de la fonction n'est pas pris en compte, donc l'intervalle de temps entre la fin d'une exécution et le début d'une autre peut varier. | L'appel récursif à setTimeout est utilisé à la place de setInterval lorsqu'une pause fixe entre les exécutions est nécessaire. | | Retard | Délai minimum : 4 ms. | Délai minimum : 4 ms. | | Fonctionnalités du navigateur | La latence 0 ne fonctionne pas dans IE | Dans Opera, une latence nulle équivaut à 4 ms et les autres délais sont gérés avec précision, notamment 1 ms, 2 ms et 3 ms non standard. |

    © 2024 ermake.ru -- À propos de la réparation de PC - Portail d'information