Opakujte akce v zadaném časovém intervalu javascriptu. Příklady funkce jQuery setTimeout()

Domov / Technologie

Metoda setInterval() nabízená na rozhraních Window a Worker opakovaně volá funkci nebo provádí úryvek kódu s pevným časovým zpožděním mezi každým voláním.

Vrací ID intervalu, které jedinečně identifikuje interval, takže jej můžete později odstranit voláním clearInterval() . Tato metoda je definována mixinem WindowOrWorkerGlobalScope. Syntax = var intervalID rozsah .setInterval(, func, [zpoždění, arg1, ...]); Syntax = var intervalID rozsah arg2, func kód ); Parametry func Funkce, která se má provést po každé milisekundě zpoždění. Funkce nejsou předány žádné argumenty a neočekává se žádná návratová hodnota. kód Volitelná syntaxe vám umožňuje zahrnout řetězec místo funkce, která se zkompiluje a spustí s každým zpožděním milisekund. Tato syntaxe je .setInterval( nedoporučuje se

ze stejných důvodů, kvůli kterým je použití eval() bezpečnostním rizikem. zpoždění Čas v milisekundách (tisíciny sekundy), který by měl časovač zpozdit mezi prováděním zadané funkce nebo kódu. Podrobnosti o povoleném rozsahu hodnot zpoždění viz níže. arg1, ..., argN Nepovinné Další argumenty, které jsou předány funkci určené pomocí

jakmile časovač vyprší.

Poznámka: Předávání dalších argumentů do setInterval() v první syntaxi nefunguje

Internet Explorer

9 a dříve. Pokud chcete v tomto prohlížeči povolit tuto funkci, musíte použít polyfill (viz část).

Návratová hodnota

Vrácené intervalID je číselná, nenulová hodnota, která identifikuje časovač vytvořený voláním setInterval() ; tato hodnota může být předána ke zrušení časového limitu.

Var intervalID = window.setInterval(myCallback, 500, "Parametr 1", "Parametr 2"); function myCallback(a, b) ( // Váš kód zde // Parametry jsou čistě volitelné. console.log(a); console.log(b); )

Příklad 2: Střídání dvou barev

Následující příklad volá funkci flashtext() jednou za sekundu, dokud nestisknete tlačítko Stop.

setInterval/clearInterval příklad 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" je ternární operátor. ) funkce stopTextColor() ( clearInterval(nIntervId); )

Ahoj světe

Zastávka

Příklad 3: Simulace psacího stroje

Následující příklad simuluje psací stroj nejprve vymazáním a poté pomalým psaním obsahu do seznamu NodeList, který odpovídá zadané skupině selektorů.< 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; */ }

JavaScript Typewriter - MDN Příklad funkce Psací stroj (sSelector, nRate) ( funkce clean () ( clearInterval(nIntervId); bTyping = false; bStart = true; oCurrent = null; aSheets.length = nIdx = 0; ) funkce rolování (oSheet, nPos , bEraseAndStop) ( if (!oSheet.hasOwnProperty("části") || aMap.length

CopyLeft 2012 od Mozilla Developer Network

[ Přehrát | Pauza | Ukončit]

Vivamus blandit massa ut metus mattis in fringilla lectus imperdiet. Proin ac ante a felis ornare vehicula. Fusce pellentesque lacus vitae eros convallis ut mollis magna pellentesque. Pellentesque placerat enim at lacus ultricies vitae facilisis nisi fringilla. V tincidunt tincidunt tincidunt.

JavaScript psací stroj
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. Integer 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. Maecenas vestibulum mollis nunc in 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 nec. Curabitur elementum nisi a eros rutrum nec blandit diam placerat. Aenean tincidunt risus ut nisi consectetur cursus. Ut vitae quam elita. 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.

Argumenty zpětného volání

Jak bylo uvedeno dříve, Internet Explorer verze 9 a nižší nepodporují předávání argumentů funkci zpětného volání v setTimeout() ani setInterval() . Následující kód specifický pro IE ukazuje metodu, jak toto omezení překonat. Chcete-li použít, jednoduše přidejte následující kód do horní části skriptu.

/*\ |*| |*| Polyfill specifický pro IE, který umožňuje průchod libovolných argumentů do |*| funkce zpětného volání javascriptových časovačů (standardní syntaxe HTML5)..setInterval |*| https://site/User:fusionchess |*| |*| Syntaxe: |*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]); |*| var timeoutID = window.setTimeout(kód, zpoždění); |*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]); |*| var intervalID = window.setInterval(kód, zpoždění); |*| \*/ if (document.all && !window.setTimeout.isPolyfill) ( var __nativeST__ = window.setTimeout; window.setTimeout = funkce (vCallback, nDelay /*, argumentToPass1, argumentToPass2 atd. */) ( var aArgs = Array .prototype.slice.call(arguments, 2) return __nativeST__(vCallback instanceof Function () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay if (document.all && !window.setInterval.isPolyfill) ( var __nativeSI__ = window.setInterval; window.setInterval = funkce (vCallback, nDelay /*, argumentToPass1, argumentToPass2 atd. */) ( var aArgs = Array.prototype. slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Funkce () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay );

Další možností je použití anonymní funkce pro zavolání zpětného volání, i když toto řešení je o něco dražší. Příklad:

Var intervalID = setInterval(function() ( myFunc("jeden", "dva", "tři"); ), 1000);

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

Neaktivní karty Vyžaduje Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)

Počínaje Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) jsou intervaly na neaktivních kartách omezeny tak, aby se spouštěly maximálně jednou za sekundu.

"Tento" problém

Když předáte metodu setInterval() nebo jiné funkci, je vyvolána s nesprávnou hodnotou. Tento problém je podrobně vysvětlen v referenci JavaScriptu.

Vysvětlení

MyArray = ["nula", "jedna", "dva"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); myArray.myMethod(); // vypíše "nula,jedna,dva" myArray.myMethod(1); // vypíše "jeden" setTimeout(myArray.myMethod, 1000); // vytiskne "" po 1 sekundě setTimeout(myArray.myMethod, 1500, "1"); // po 1,5 sekundách vypíše "undefined" // předání objektu "this" pomocí .call nebude fungovat // protože to změní hodnotu tohoto uvnitř samotného setTimeout // zatímco my chceme změnit hodnotu tohoto uvnitř myArray .myMethod // ve skutečnosti to bude chyba, protože kód setTimeout očekává, že to bude objekt okna: setTimeout.call(myArray, myArray.myMethod, 2000 // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Neplatná operace na objektu WrappedNative prototype); setTimeout.call(myArray, myArray.myMethod, 2500, 2);

Jak vidíte, neexistují žádné způsoby, jak předat tento objekt funkci zpětného volání ve starším JavaScriptu.

Možné řešení

Možným způsobem, jak vyřešit „tento“ problém, je nahradit dvě nativní globální funkce setTimeout() nebo setInterval() dvěma nepůvodní takové, které umožňují jejich vyvolání prostřednictvím metody Function.prototype.call. Následující příklad ukazuje možnou náhradu:

// Povolí průchod „tohoto“ objektu přes časovače JavaScriptu var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = funkce (vCallback, nDelay /*, argumentToPass1, argumentToPass2 atd. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Funkce ? funkce () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay ); window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2 atd. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Funkce ? funkce () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay );

Tyto dvě náhrady také umožňují standardní přechod libovolných argumentů do funkcí zpětného volání časovačů v IE standardu HTML5. Lze je tedy použít jako nestandardně vyhovující polyfilly také. Viz a vyhovující normě polyfill.

Test nových funkcí:

MyArray = ["nula", "jedna", "dva"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); setTimeout(upozornění, 1500, "Ahoj světe!"); // standardní použití setTimeout a setInterval je zachováno, ale... setTimeout.call(myArray, myArray.myMethod, 2000); // po 2 sekundách vypíše "nula,jedna,dva" setTimeout.call(myArray, myArray.myMethod, 2500, 2); // vytiskne "dva" po 2,5 sekundách

Pro složitější, ale stále modulární verzi ( Démon) viz Správa démonů JavaScriptu . Tato složitější verze není nic jiného než velká a škálovatelná sbírka metod pro Démon konstruktér. Nicméně, Démon konstruktor sám o sobě není nic jiného než klon MiniDaemon s přidanou podporou init a nastartovat funkce deklarované během vytváření instance démon. Takže MiniDaemon framework zůstává doporučeným způsobem pro jednoduché animace, protože Démon bez jeho sbírky metod je v podstatě jeho klonem.

minidaemon.js /*\ |*| |*| :: MiniDaemon:: |*| |*| Revize #2 – 26. září 2014.setInterval |*| https://site/User:fusionchess |*| https://github.com/madmurphy/minidaemon.js |*| |*| Tento rámec je vydán pod licencí GNU Lesser General Public License, verze 3 nebo novější. |*| http://www.gnu.org/licenses/lgpl-3.0.html |*| \*/ funkce 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 = Infinity;< 1: this.INDEX + 1 >tato.délka; ); 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 = funkce (bReverse) ( var bBackw = Boolean(bReverse); if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) ( return; ) this.BACKW = bBackw toto.PAUSED = false.synchronize();

MiniDaemon předává argumenty funkci zpětného volání. Pokud na něm chcete pracovat s prohlížeči, které tuto funkci nativně nepodporují, použijte jednu z výše navržených metod.

Syntax

var myDaemon = nový MiniDaemon( tentoObjekt, zpětné volání[ , hodnotit [, délka]]);

Popis Poznámky k použití

Funkce setInterval() se běžně používá k nastavení zpoždění pro funkce, které se spouštějí znovu a znovu, jako jsou animace. Interval můžete zrušit pomocí WindowOrWorkerGlobalScope.clearInterval() .

Pokud si přejete zavolat svou funkci jednou po zadaném zpoždění použijte .

Omezení zpoždění

Je možné, aby byly intervaly vnořeny; to znamená, že zpětné volání pro setInterval() může zase volat setInterval() ke spuštění dalšího intervalu, i když ten první stále běží. Aby se zmírnil potenciální dopad, který to může mít na Jakmile jsou intervaly vnořeny za hranicí pěti úrovní, prohlížeč automaticky vynutí minimální hodnotu 4 ms pro interval Pokusy zadat hodnotu menší než 4 ms v hluboce vnořených voláních setInterval() budou připnuty na 4 ms.

Prohlížeče mohou za určitých okolností vynutit ještě přísnější minimální hodnoty intervalu, i když by to nemělo být běžné. Všimněte si také, že skutečná doba, která uplyne mezi voláními zpětného volání, může být delší než dané zpoždění; příklady najdete v části Důvody pro zpoždění delší, než je uvedeno v WindowOrWorkerGlobalScope.setTimeout().

Ujistěte se, že doba provádění je kratší než intervalová frekvence

Pokud existuje možnost, že provedení vaší logiky bude trvat déle, než je časový interval, doporučuje se rekurzivně zavolat pojmenovanou funkci pomocí setTimeout() . Pokud například použijete metodu setInterval() k dotazování vzdáleného serveru každých 5 sekund, latence sítě, neodpovídající server a řada dalších problémů může zabránit dokončení požadavku ve stanoveném čase. Proto se můžete ocitnout ve frontě s požadavky XHR, které se nemusí nutně vrátit v pořádku.

Při programování ve skriptovacích jazycích je periodicky potřeba vytvořit pauzu - na chvíli pozastavit provádění programu a pak pokračovat v práci. Například ve skriptech VBS a PHP jsou možné následující metody:

VBS: wscript.sleep 1500 (zastavení na 1,5 sekundy)

PHP: spánek(10); (zastavte se na 10 sekund)

Během takových přestávek běží runtime systém (PHP nebo VBS) nedělá nic. Vývojář, který se snaží intuitivně použít něco podobného v Javascriptu, bude nemile překvapen. Běžná chyba při pokusu o vytvoření pauzy v Javascriptu to vypadá takto:

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

Myslíte si, že když během cyklu přijde řada na kreslení dalšího čísla, váš setTimeout poctivě zastaví Javascript v práci, počká 0,9 sekundy, přidá požadované číslo na konec vstupního pole a pak pokračuje v práci. Ale ve skutečnosti tomu tak není: setInterval a setTimeout v Javascriptu pouze zdržují provedení akce (nebo funkce) uvedené v závorkách. V našem příkladu se stane následující:

  • i = 1;
  • zpoždění přidání čísla "1" do vstupního pole o 0,9 sekundy;
  • Ihned po nastavení tohoto problému cyklus pokračuje: i=2;
  • zpoždění přidání čísla "2" do vstupního pole o 0,9 sekundy;
  • Okamžitě znamená například 1 ms (tedy neúměrně málo ve srovnání s 900 ms): smyčka vykoná svou práci téměř okamžitě a vytvoří několik odložených úloh ze stejného okamžiku. To znamená, že všechny nevyřízené úkoly „kreslení“ budou dokončeny téměř ve stejnou dobu, bez pauz mezi přidáváním nových čísel. Cyklus začíná; vše zamrzne na 0,9 s; a shirr - všechna čísla jsou střílena v řadě za sebou.

    Jak v takovém případě správně použít setTimeout? Je to složité. Budete muset zavolat funkci rekurzivně(v rámci funkce stejná funkce), a aby tento proces nebyl nekonečný, nastavte podmínku zastavení (například velikost čísla, které se má vytisknout):

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

    A proměnná i bude muset být inicializována mimo funkci - například takto:

    Nyní vše funguje jak má (zkrátili jsme dobu zpoždění z 0,9 s na 0,4 s). Ale pro takové úkoly je logičtější použít setInterval spíše než setTimeout (i když to bude vyžadovat dvě funkce):

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

    Zvláštností metody Javascirpt setInterval je, že neprochází „sama od sebe“ a musí být zastavena speciální metodou clearInterval. A aby bylo jasné, co přesně zastavit, je úkolu pro odloženou akci přiřazen speciální identifikátor - časovač: window.timer1 = window.setInterval(...) .

    Úkolům vytvořeným metodou setTimeout lze také přiřadit identifikátory. Všechna ID časovače musí být navzájem odlišná (unikátní v aktuálním okně prohlížeče). V okně pak můžete vytvořit několik různých úloh, které využívají odložené akce, a tyto úlohy se budou provádět paralelně (tak nějak současně, pokud má počítač dostatek prostředků), což je v PHP nebo VBS v podstatě nemožné.

    Zde je příklad stránky s několika Javascriptovými časovači spuštěnými současně: setinterval.htm (funkce JavaScriptu v souboru setinterval.js). Všechny časovače stránky (kromě menu) lze zastavit klávesou Esc. Všechny příklady časovačů jsou založeny na „přirozeném“ (a nikoli abstraktním i++) odpočítávání – času nebo vzdálenosti. Všechny „hodiny“ jsou speciálně desynchronizované (pro přehlednost). Časovače závislé na vzdálenosti se používají v „indikátoru“ a v rozbalovací („rozbalovací“) nabídce.

    Rozbalovací nabídka

    Naše posuvné menu je ve skutečnosti posuvné (zpod „záhlaví“): mezi prvky jsou speciálně ponechány mezery, takže můžete vidět, jak se vysouvá. Nečekaně se ukázalo, že stejně hladký výstup u různě dlouhých seznamů nedokážeme udělat – pravděpodobně kvůli nízkému výkonu počítače (AMD Athlon 999 MHz).

    Je zcela zřejmé, že pro krásu a harmonii je nutné, aby se seznamy různých položek menu objevovaly současně. To znamená, že delší seznamy by měly vypadnout s více vysoká rychlost, kratší - při nižší rychlosti. Zdá se, že by to mohlo být implementováno takto:

  • Celkový čas „odjezdu“ nastavíme např. na 200 ms.
  • Pokud má rozbalovací seznam výšku 20 px, je zřejmé, že jej můžeme posunout o jeden pixel dolů za 10 ms interval – a pak za 200 ms vyjede celý seznam.
  • Pokud je rozevírací seznam vysoký 40 pixelů, abychom se vešli za stejnou dobu, musíme jej každých 5 ms posunout o jeden pixel dolů.
  • Podle této logiky, pokud je rozevírací seznam vysoký 200 pixelů, měli bychom jej posunout o jeden pixel dolů každou 1 ms. Taková rychlost ale na našem počítači nefunguje – prohlížeč prostě nestihne nakreslit novou pozici seznamu za jednu milisekundu. Ano. Javascript zvládá počítat (co se tam má počítat?), ale prohlížeč (Firefox) nestihne zobrazit. Typická situace pro web.

    Proto je možné víceméně vyrovnat čas odchodu z menu pouze pomocí berliček a stále není jasné, jak to bude fungovat déle rychlý počítač. Ale měli bychom počítat s tím nejpomalejším, že? Algoritmus (bez zohlednění rychlosti počítače) vypadá asi takto:

  • Nastavte celkový čas pro kontrolu seznamu: čas = 224 (ms).
  • Nastavíme minimální čas pro jeden interval v cyklu: zpoždění = 3 (ms).
  • Nastavte minimální krok pro přesun seznamu: offset = 1 (px).
  • To vše měníme v závislosti na výšce seznamu: 1) zvyšujeme čas zpoždění (intervalu) nepřímo úměrně výšce a přímo úměrně celkovému času času (při výšce 224 je koeficient 1); 2) pokud je výška větší než 40 px, zvyšte minimální krok v poměru k výšce. Konstanta "40" byla získána experimentálně pro nejpomalejší počítač. Testy na počítači Pentium 4 CPU 2,53GHz odhalily úplně stejné číslo – 40. V opačném případě se časovače vyřadí z provozu, seznamy vyjdou z kroku.
  • Nyní seznamy víceméně vycházejí. Na víceméně podobnou dobu. Na stránce setinterval.htm.

    A tady přichází Bruce:

    Funkce 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 } } }

    Samotná funkce, která vytlačí vnořené seznamy z nabídky, je, jak vidíme, velmi jednoduchá. Vše, co zbývá, je spustit jej s něčím jako je tento řádek:

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

    Než začnete, stačí vypočítat všechny tyto maxtop a offset a také umístit seznam na pozici mintop. To je to, co dělá „předběžná“ funkce slide() o 40 řádcích. A to vše dohromady – v souboru setinterval.js. Ano, a bez přiloženého souboru stylů tato kravina vůbec nebude fungovat

    Je nesmírně důležité pochopit, jak fungují časovače JavaScriptu. Jejich chování často neodpovídá našemu intuitivnímu chápání multithreadingu, a to je způsobeno tím, že ve skutečnosti jsou prováděny v jediném vláknu. Podívejme se na čtyři funkce, pomocí kterých můžeme spravovat časovače:

    • var id = setTimeout(fn, zpoždění); - Vytvoří jednoduchý časovač, který zavolá danou funkci po daném zpoždění. Funkce vrací jedinečné ID, pomocí kterého lze časovač pozastavit.
    • var id = setInterval(fn, zpoždění); - Podobné jako setTimeout, ale nepřetržitě volá funkci v daném intervalu (až do zastavení).
    • clearInterval(id);, clearTimeout(id); - Přijímá ID časovače (vrácené jednou z funkcí popsaných výše) a zastaví provádění zpětného volání"a.
    Hlavní myšlenkou, kterou je třeba vzít v úvahu, je, že není zaručena přesnost doby zpoždění časovače. Za prvé, prohlížeč provádí všechny asynchronní události JavaScriptu v jednom vlákně (jako jsou kliknutí myší nebo časovače) a pouze v době, kdy je na řadě tato událost. Nejlépe to ukazuje následující diagram:

    Tento obrázek obsahuje poměrně hodně informací, ale jejich pochopení vám poskytne hlubší pochopení toho, jak funguje asynchronie JavaScriptu. Tento graf představuje čas vertikálně v milisekundách, modré bloky ukazují bloky kódu JavaScript, které byly provedeny. Například první blok je proveden v průměru za 18 ms, kliknutí myší blokuje provedení na přibližně 11 ms atd.

    JavaScript může spustit pouze jeden kus kódu (kvůli jednovláknové povaze provádění), z nichž každý blokuje provádění jiných asynchronních událostí. To znamená, že když dojde k asynchronní události (například kliknutí myší, volání časovače nebo dokončení požadavku XMLHttp), je přidána do fronty a spuštěna později (implementace se samozřejmě liší podle prohlížeče, ale domluvme se na nazývat to „fronta“).

    Pro začátek si představme, že dva časovače začínají uvnitř bloku JavaScriptu: setTimeout se zpožděním 10 ms a setInterval se stejným zpožděním. Podle toho, kdy se časovač spustí, se spustí v okamžiku, kdy ještě nemáme dokončený první blok kódu. Všimněte si však, že se nespustí okamžitě (to není možné kvůli jedinému závitu). Místo toho je odložená funkce zařazena do fronty a spuštěna v příštím dostupném okamžiku.

    Během provádění prvního bloku JavaScriptu také dojde ke kliknutí myší. Obslužnou rutinu této asynchronní události (a ta je asynchronní, protože ji nemůžeme předvídat) nelze v tuto chvíli provést okamžitě, takže také skončí ve frontě, jako časovač.

    Po provedení prvního bloku kódu JavaScript se prohlížeč zeptá: „Co čeká na spuštění?“ V v tomto případě Ovladač kliknutí myší a časovač jsou ve stavu čekající na vyřízení. Prohlížeč vybere jeden z nich (obslužný program kliknutí) a spustí jej. Časovač bude čekat na další dostupnou část času ve frontě provádění.

    Všimněte si, že zatímco se provádí obslužná rutina kliknutí myší, spustí se první intervalové zpětné volání. Stejně jako zpětné volání časovače bude zařazeno do fronty. Pamatujte však, že když se interval znovu spustí (během zpětného volání časovače), bude odstraněn z fronty. Pokud by všechna zpětná volání v intervalu byla zařazena do fronty během provádění velkého kusu kódu, vedlo by to ke spoustě funkcí čekajících na zavolání, aniž by mezi nimi došlo k žádné prodlevě při dokončení provádění. Místo toho mají prohlížeče tendenci čekat, dokud nebudou žádné další funkce vlevo ve frontě před přidáním dalšího do fronty.

    Můžeme tedy pozorovat případ, kdy se třetí odpálení intervalového zpětného volání shoduje s okamžikem, kdy je již provedeno. To ilustruje důležitý bod: intervaly se nestarají o to, co právě běží, budou přidány do fronty bez ohledu na prodlevu mezi spuštěními.

    Nakonec, po dokončení druhého intervalového zpětného volání, uvidíme, že už nezbývá nic, co by JavaScriptový engine mohl spustit. To znamená, že prohlížeč opět čeká na nové asynchronní události. K tomu dojde při značce 50 ms, kdy bude opět fungovat intervalové zpětné volání. V tuto chvíli už to nebude nic blokovat, takže to bude fungovat okamžitě.

    Podívejme se na příklad, který pěkně ilustruje rozdíl mezi setTimeout a setInterval.
    setTimeout(function())( /* Nějaký dlouhý blok kódu... */ setTimeout(arguments.callee, 10); ), 10);
    setInterval(function())( /* Nějaký dlouhý blok kódu... */ ), 10);

    Tyto dvě možnosti jsou na první pohled rovnocenné, ale ve skutečnosti nejsou. Kód používající setTimeout bude mít vždy zpoždění alespoň 10 ms po předchozím volání (může to být více, ale nikdy méně), zatímco kód používající setInterval bude mít tendenci volat každých 10 ms, bez ohledu na to, kdy došlo k předchozímu volání.
    Pojďme si shrnout vše, co bylo řečeno výše:
    - Funkce setTimeout a setInterval se v asynchronním kódu provádějí zásadně odlišně,
    - Pokud nelze časovač spustit v momentálně, bude zpožděn do dalšího bodu provedení (který bude delší než požadované zpoždění),
    - Intervaly (setInterval) mohou být provedeny jeden po druhém bez zpoždění, pokud jejich provedení trvá déle než zadaná prodleva.

    To vše je extrémně důležité informace pro rozvoj. Znalost toho, jak funguje JavaScript engine, zvláště se spoustou asynchronních událostí (což se často stává), pokládá skvělý základ pro vytváření pokročilých aplikací.

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

    Téměř všechny implementace JavaScriptu mají interní plánovač časovače, který vám umožňuje naplánovat volání funkce po určité době.

    Tato funkce je podporována zejména v prohlížečích a na serveru Node.JS.

    setTimeout

    Syntax:

    var timerId = setTimeout(funkce/kód, zpoždění[, arg1, arg2...])

    Parametry:

    • funkce/kód
      • Funkce nebo řádek kódu, který se má provést.
      • Řetězec je zachován kvůli kompatibilitě a nedoporučuje se.
    • func
      • Latence v milisekundách, 1000 milisekund se rovná 1 sekundě.
    • arg1, arg2…
      • Argumenty k předání funkci. Není podporováno v IE9-.
      • Funkce bude vykonána po čase zadaném v parametru delay.

    Například následující kód spustí výstrahu ("Ahoj") po jedné sekundě:

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

    Pokud je prvním argumentem řetězec, pak interpret z tohoto řetězce vytvoří anonymní funkci.

    To znamená, že tento záznam funguje úplně stejně:

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

    Místo toho použijte anonymní funkce:

    SetTimeout(funkce () ( alert("Ahoj" ) ), 1000 );

    Parametry pro funkci a kontext

    Ve všech moderní prohlížeče Vzhledem k IE10 vám setTimeout umožňuje specifikovat parametry funkcí.

    Níže uvedený příklad vypíše „Ahoj, já jsem Vasya“ všude kromě IE9-:

    funkce sayHi (kdo) ( alert("Ahoj, já jsem " + kdo); ) setTimeout(sayHi, 1000 , "Vasya" );

    ...Ve většině případů však potřebujeme podporu ze starého IE a ten vám neumožňuje specifikovat argumenty. Proto, aby je převedli, zabalí hovor do anonymní funkce:

    funkce sayHi (kdo) ( alert("Ahoj, já jsem " + kdo); ) setTimeout(function () ( sayHi("Vasya") ), 1000 );

    Volání setTimeout neprojde tímto kontextem.

    Zejména volání metody objektu přes setTimeout bude fungovat v globálním kontextu. To může vést k nesprávným výsledkům.

    Zavolejte například user.sayHi() po jedné sekundě:

    funkce Uživatel (id) funkce () ( alert(toto .id); ); ) var user = new User(12345); setTimeout(user.sayHi, 1000); // očekává se 12345, ale vypíše "undefined"

    Protože setTimeout spustí funkci user.sayHi v globálním kontextu, nebude mít přístup k objektu prostřednictvím tohoto .

    Jinými slovy, tato dvě volání pro setTimeout dělají totéž:

    // (1) jeden řádek setTimeout(user.sayHi, 1000); // (2) totéž na dvou řádcích var func = user.sayHi; setTimeout(func, 1000 );

    Naštěstí je tento problém také snadno vyřešen vytvořením mezilehlé funkce:

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

    Funkce wrapper se používá k předávání argumentů napříč prohlížeči a zachování kontextu provádění.

    Zrušení exekuce

    Funkce setTimeout vrací timerId, který lze použít ke zrušení akce.

    Syntax:

    ClearTimeout(timerId)

    V následujícím příkladu nastavíme časový limit a poté smažeme (rozmysleli jsme si to). Ve výsledku se nic neděje.

    var timerId = setTimeout(funkce () ( alert(1) ), 1000 ); clearTimeout(timerId); nastavitInterval

    Metoda setInterval má syntaxi podobnou setTimeout.

    var timerId = setInterval(funkce/kód, zpoždění[, arg1, arg2...])

    Význam argumentů je stejný. Na rozdíl od setTimeout ale funkci nespustí jednou, ale pravidelně ji opakuje v zadaném časovém intervalu. Provádění můžete zastavit voláním:

    ClearInterval(timerId)

    V následujícím příkladu se při spuštění zobrazí zpráva každé dvě sekundy, dokud neklepnete na tlačítko Zastavit:

    var i = 1;

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

    Řazení a překrývání hovorů v setInterval

    Volání setInterval(funkce, zpoždění) způsobí, že se funkce provede v zadaném časovém intervalu. Ale je tu jemnost.

    Ve skutečnosti je pauza mezi hovory kratší než zadaný interval.

    To znamená, že prohlížeč zahájí spuštění funkce úhledně každých 100 ms, aniž by zohlednil dobu provádění samotné funkce.

    Stává se, že provedení funkce trvá déle, než je zpoždění. Například funkce je složitá, ale zpoždění je malé. Nebo funkce obsahuje upozornění/potvrzení/výzvy, které blokují spouštěcí vlákno. Tady to začíná být zajímavé.

    Pokud funkci nelze spustit, protože je prohlížeč zaneprázdněn, bude zařazena do fronty a spuštěna, jakmile bude prohlížeč volný.

    Obrázek níže ukazuje, co se stane u funkce, jejíž provedení trvá dlouho.

    Volání funkce iniciované příkazem setInterval je přidáno do fronty a proběhne okamžitě, pokud je to možné:

    K druhému spuštění funkce dojde ihned po skončení prvního:

    Provedení není zařazeno do fronty více než jednou.

    Pokud spuštění funkce trvá déle než několik plánovaných spuštění, bude stále jednou zařazena do fronty. Nedochází tedy k „hromadění“ startů.

    Na obrázku níže se setInterval pokusí provést funkci za 200 ms a zařadí volání do fronty. Po 300 ms a 400 ms se časovač znovu probudí, ale nic se neděje.

    Volání setInterval(funkce, zpoždění) nezaručuje skutečné zpoždění mezi provedeními.

    Existují případy, kdy je skutečné zpoždění větší nebo menší než zadané. Obecně není pravda, že bude alespoň nějaké zpoždění.

    Opakování vnořeného setTimeout

    V případech, kdy je potřeba nejen pravidelné opakování, ale je vyžadována prodleva mezi běhy, setTimeout se používá k opětovnému nastavení při každém provedení funkce.

    Níže je uveden příklad, který vydává výstrahu s intervalem 2 sekund mezi nimi.

    var i = 1;

    var timer = setTimeout(spuštění funkce () ( alert(i++); timer = setTimeout(run, 2000); ), 2000 );

    Časová osa provádění bude mít pevné zpoždění mezi spuštěními. Ilustrace pro zpoždění 100 ms:

    Minimální zpoždění časovače

    Časovač prohlížeče má nejnižší možnou latenci. V moderních prohlížečích se pohybuje přibližně od nuly do 4 ms. U starších může být delší a dosáhnout 15 ms.

    Podle normy je minimální zpoždění 4 ms. Není tedy žádný rozdíl mezi setTimeout(..,1) a setTimeout(..,4) .

  • Chování setTimeout a setInterval s nulovou latencí je specifické pro prohlížeč.
  • V aplikaci Internet Explorer nebude fungovat nulové zpoždění setInterval(.., 0). To platí konkrétně pro setInterval , tj. setTimeout(.., 0) funguje dobře.
  • Skutečná spouštěcí frekvence

    Spouštění může být mnohem méně časté V některých případech nemusí být zpoždění 4 ms, ale 30 ms nebo dokonce 1000 ms.

    Většina prohlížečů (především pro stolní počítače) nadále provádí setTimeout / setInterval, i když je karta neaktivní. Zároveň řada z nich (Chrome, FF, IE10) snižuje minimální frekvenci časovače na 1x za sekundu. Ukazuje se, že časovač bude fungovat na kartě „pozadí“, ale zřídka.

    Při provozu na baterii na notebooku mohou prohlížeče také snížit frekvenci, aby spouštěly kód méně často a šetřily energii baterie. IE je tím zvláště známý. Snížení může dosáhnout několikanásobku, v závislosti na nastavení. Pokud je zatížení procesoru příliš vysoké, JavaScript nemusí být schopen zpracovat časovače včas. Tím přeskočíte některé běhy setInterval.

    Závěr: frekvence 4 ms stojí za pozornost, ale neměli byste s ní počítat.

    Intervaly výstupu do konzole Kód, který počítá časové intervaly mezi voláními, vypadá asi takto:

    var timeMark = new Date; setTimeout(funkce go () ( var diff = new Date - timeMark; // vytiskne další zpoždění do konzole místo na stránku console .log(diff); // zapamatovat si čas na samém konci, // pro měření prodleva mezi hovory timeMark = new Date ; setTimeout(go, 100 ), 100 ); Trik je setTimeout(func, 0)

    Tento trik stojí za to vstoupit do análů hacků JavaScriptu.

    Funkce je zabalena do setTimeout(func, 0), pokud ji chcete spustit po skončení aktuálního skriptu.

    Jde o to, že setTimeout nikdy neprovede funkci okamžitě. Plánuje pouze její realizaci. Ale interpret JavaScriptu začne provádět plánované funkce až po provedení aktuálního skriptu.

    Podle standardu nemůže setTimeout provést funkci se zpožděním 0, jak jsme již řekli, zpoždění bude obvykle 4 ms. Ale hlavní věc je, že provedení v každém případě proběhne po provedení aktuálního kódu.

    Například:

    var výsledek; funkce showResult () ( alert(vysledek); ) setTimeout(showResult, 0 ); výsledek = 2 * 2 ; // vypíše 4 Total

    Metody setInterval(func, delay) a setTimeout(func, delay) vám umožňují spouštět funkci func pravidelně/jednou za každou milisekundu zpoždění.

    Obě metody vrátí ID časovače. Používá se k zastavení provádění voláním clearInterval / clearTimeout .

    | | nastavitInterval | setTimeout | || ----------- | ---------- | | Načasování | Hovor je přísně na časovač. Pokud je tlumočník zaneprázdněn, je jeden hovor zařazen do fronty. Doba provádění funkce se nebere v úvahu, takže časový interval od konce jednoho běhu do začátku druhého se může lišit. | Rekurzivní volání setTimeout se používá místo setInterval, kde je potřeba pevná pauza mezi spuštěními. | | Zpoždění | Minimální zpoždění: 4 ms. | Minimální zpoždění: 4 ms. | | Funkce prohlížeče | Latence 0 nefunguje v IE | V Opeře je nulová latence ekvivalentní 4 ms a další zpoždění jsou zpracována přesně, včetně nestandardních 1 ms, 2 ms a 3 ms. |

    © 2024 ermake.ru -- O opravě PC - Informační portál