Pakartokite veiksmus nurodytu JavaScript laiko intervalu. Funkcijos jQuery setTimeout() pavyzdžiai

Pradžia / Technologijos

Metodas setInterval(), siūlomas „Window“ ir „Worker“ sąsajose, pakartotinai iškviečia funkciją arba vykdo kodo fragmentą su fiksuotu laiko tarpu tarp kiekvieno iškvietimo.

Jis grąžina intervalo ID, kuris unikaliai identifikuoja intervalą, todėl vėliau galėsite jį pašalinti iškviesdami clearInterval() . Šį metodą apibrėžia WindowOrWorkerGlobalScope maišytuvas. Sintaksė = var intervalID apimtis .setInterval(, func, [delsimas, arg1, ...]); Sintaksė = var intervalID apimtis arg2, func kodas ); Parameters func Funkcija, kuri turi būti vykdoma kas delsos milisekundes. Funkcijai nepateikiami jokie argumentai ir nesitikima grąžinti vertės. kodas Neprivaloma sintaksė leidžia vietoj funkcijos įtraukti eilutę, kuri sukompiliuojama ir vykdoma kas delsos milisekundes. Ši sintaksė yra .setInterval( nerekomenduojama

dėl tų pačių priežasčių, dėl kurių naudojant eval() kyla pavojus saugumui. uždelsimas Laikas milisekundėmis (tūkstančiomis sekundės dalimis), kurį laikmatis turi uždelsti tarp nurodytos funkcijos ar kodo vykdymo. Daugiau informacijos apie leistiną delsos verčių diapazoną rasite toliau. arg1, ..., argN Neprivaloma Papildomi argumentai, kurie perduodami funkcijai, nurodytai

pasibaigus laikmačiui.

Pastaba: papildomų argumentų perdavimas setInterval() pirmoje sintaksėje neveikia

Internet Explorer

9 ir anksčiau. Jei norite įjungti šią funkciją toje naršyklėje, turite naudoti polifillą (žr. skyrių).

Grąžinimo vertė

Grąžintas intervalID yra skaitinė, ne nulis reikšmė, kuri identifikuoja laikmatį, sukurtą iškvietus setInterval() ; Šią reikšmę galima perduoti norint atšaukti skirtąjį laiką.

Var intervalID = window.setInterval(myCallback, 500, "Parameter 1", "Parameter 2"); function myCallback(a, b) ( // Jūsų kodas čia // Parametrai yra visiškai neprivalomi. console.log(a); console.log(b); )

2 pavyzdys: dviejų spalvų kaitaliojimas

Toliau pateiktame pavyzdyje funkcija flashtext() iškviečiama kartą per sekundę, kol paspaudžiamas sustabdymo mygtukas.

setInterval/clearInterval pavyzdys var nIntervId;

function changeColor() ( nIntervId = setInterval(flashText, 1000); ) function flashText() ( var oElem = document.getElementById("mano_dėžutė"); oElem.style.color = oElem.style.color == "raudona" ? " mėlyna" : "raudona"; // oElem.style.color == "raudona" ? "mėlyna" : "raudona" yra trejopas operatorius. ) funkcija stopTextColor() ( clearInterval(nIntervId); )

Sveikas pasaulis

Sustok

3 pavyzdys: Rašomosios mašinėlės modeliavimas

Toliau pateiktame pavyzdyje modeliuojama rašomosios mašinėlės, pirmiausia išvalant, o po to lėtai įvedant turinį, atitinkantį nurodytą parinktuvų grupę.< 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 rašomoji mašinėlė – MDN funkcijos Rašomosios mašinėlės pavyzdys (sSelector, nRate) ( funkcija švarus () ( clearInterval(nIntervId); bTyping = false; bStart = true; oCurrent = null; aSheets.length = nIdx = 0; ) funkcija slinkti (oSheet, nPossheet , bEraseAndStop) ( if (!oSheet.hasOwnProperty("parts") || aMap.length

„Mozilla Developer Network“ „CopyLeft 2012“.

[ Žaisti | Pauzė | Nutraukti]

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. in tincidunt tincidunt tincidunt.

JavaScript rašomoji mašinėlė
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 semper libero, eu tincidunt dolor eleifend sit amet. Ut niekur kitur velit in dolor tincidunt rhoncus non non diam. Morbi auctor ornare orci, non euismod felis gravida, niekur kitur nepriskirta. Curabitur elementum nisi a eros rutrum, niekur kitur blandit diam placerat. Aenean tincidunt risus ut nisi consectetur cursus. Ut vitae 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, ir 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.

Atšaukimo argumentai

Kaip aptarta anksčiau, „Internet Explorer“ 9 ir senesnės versijos nepalaiko argumentų perdavimo atgalinio skambinimo funkcijai nei setTimeout() nei setInterval() . Šis specifinis IE kodas parodo būdą, kaip įveikti šį apribojimą. Norėdami naudoti, tiesiog pridėkite šį kodą scenarijaus viršuje.

/*\ |*| |*| IE būdingas daugialypis užpildymas, leidžiantis perduoti savavališkus argumentus į |*| „Javascript“ laikmačių atgalinio iškvietimo funkcijos (HTML5 standartinė sintaksė)..setInterval |*| https://site/User:fusionchess |*| |*| Sintaksė: |*| var timeoutID = window.setTimeout(funk, delay[, arg1, arg2, ...]); |*| var timeoutID = window.setTimeout(kodas, delsa); |*| var intervalID = langas.setInterval(funk, delsa[, arg1, arg2, ...]); |*| var intervalID = langas.setInterval(kodas, delsa); |*| \*/ if (document.all && !window.setTimeout.isPolyfill) ( var __nativeST__ = window.setTimeout; window.setTimeout = funkcija (vCallback, nDelay /*, argumentToPass1, argumentToPass2 ir kt. */) ( var aArgs = Masyvas .prototype.slice.call(argumentai, 2); return __nativeST__(vCallback instanceof Function () ( vCallback.apply(null, aArgs); ): vCallback, nDelay ); ( var __nativeSI__ = window.setInterval; window.setInterval = funkcija (vCallback, nDelay /*, argumentToPass1, argumentToPass2 ir kt. */) ( var aArgs = Array.prototype. slice.call(arguments, 2); return __nativeSI__(vCallback Funkcijos pavyzdys () ( vCallback.apply(null, aArgs); ): vCallback, nDelay );

Kita galimybė yra naudoti anoniminę funkciją, kad galėtumėte skambinti atgal, nors šis sprendimas yra šiek tiek brangesnis. Pavyzdys:

Var intervalID = setInterval(function() ( myFunc("vienas", "du", "trys"); ), 1000);

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

Neaktyviems skirtukams reikalinga „Gecko 5.0“ („Firefox 5.0“ / „Thunderbird 5.0“ / „SeaMonkey 2.2“)

Pradedant nuo „Gecko 5.0“ („Firefox 5.0“ / „Thunderbird 5.0“ / „SeaMonkey 2.2“), intervalai neaktyviuose skirtukuose suaktyvinami ne dažniau kaip kartą per sekundę.

"Šita" problema

Kai perduodate metodą setInterval() arba bet kuriai kitai funkcijai, jis iškviečiamas neteisingai nurodant šią reikšmę. Ši problema išsamiai paaiškinta „JavaScript“ nuorodoje.

Paaiškinimas

MyArray = ["nulis", "vienas", "du"]; myArray.myMethod = funkcija (sProperty) ( alert(arguments.length > 0 ? this : this); ); myArray.myMethod(); // spausdina "nulis, vienas, du" myArray.myMethod(1); // spausdina "one" setTimeout(myArray.myMethod, 1000); // atspausdina "" po 1 sekundės setTimeout(myArray.myMethod, 1500, "1"); // atspausdina "undefined" po 1,5 sek .myMethod // iš tikrųjų tai bus klaida, nes setTimeout kodas tikisi, kad tai bus lango objektas: setTimeout.call(myArray, myArray.myMethod, 2000); setTimeout.call(myArray, myArray.myMethod, 2500, 2) // ta pati klaida

Kaip matote, nėra būdų perduoti šį objektą atgalinio skambinimo funkcijai pasenusioje „JavaScript“.

Galimas sprendimas

Galimas būdas išspręsti šią problemą yra pakeisti dvi vietines setTimeout() arba setInterval() globalias funkcijas dviem. nevietiniai tie, kurie įgalina jų iškvietimą naudojant Function.prototype.call metodą. Toliau pateiktame pavyzdyje parodytas galimas pakeitimas:

// Įgalinkite „šio“ objekto perdavimą per „JavaScript“ laikmačius var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = funkcija (vCallback, nDelay /*, argumentToPass1, argumentToPass2 ir kt. */) ( var oThis = tai, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Function ? () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay ); window.setInterval = funkcija (vCallback, nDelay /*, argumentToPass1, argumentToPass2 ir kt. */) ( var oThis = tai, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Function ? () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay );

Šie du pakaitalai taip pat įgalina HTML5 standartinį savavališkų argumentų perdavimą į IE laikmačių atgalinio iškvietimo funkcijas. Taigi jie gali būti naudojami kaip neatitinka standartų polifilai taip pat. Žiūrėkite a atitinka standartus polifilas.

Naujos funkcijos testas:

MyArray = ["nulis", "vienas", "du"]; myArray.myMethod = funkcija (sProperty) ( alert(arguments.length > 0 ? this : this); ); setTimeout(alert, 1500, "Sveikas pasaulis!"); // išsaugomas standartinis setTimeout ir setInterval naudojimas, bet... setTimeout.call(myArray, myArray.myMethod, 2000); // atspausdina "zero,one,du" po 2 sekundžių setTimeout.call(myArray, myArray.myMethod, 2500, 2); // išspausdina "du" po 2,5 sekundės

Sudėtingesnei, bet vis tiek modulinei jos versijai ( Demonas) žr. JavaScript demonų valdymą. Ši sudėtingesnė versija yra ne kas kita, kaip didelis ir keičiamo dydžio metodų rinkinys Demonas konstruktorius. Tačiau, Demonas pats konstruktorius yra ne kas kita, kaip klonas MiniDaemon su papildoma parama init ir pradžios funkcijos, deklaruotos egzistavimo metu demonas. Taigi, MiniDaemon sistema išlieka rekomenduojamas paprastas animacijos būdas, nes Demonas be jos metodų rinkinio iš esmės yra jos klonas.

minidaemon.js /*\ |*| |*| :: MiniDaemon:: |*| |*| 2 peržiūra – 2014 m. rugsėjo 26 d.setInterval |*| https://site/User:fusionchess |*| https://github.com/madmurphy/minidaemon.js |*| |*| Ši sistema yra išleista pagal GNU Lesser General Public License, 3 arba naujesnę versiją. |*| http://www.gnu.org/licenses/lgpl-3.0.html |*| \*/ funkcija MiniDaemon (oOwner, fTask, nRate, nLen) ( if (!(this && this MiniDaemon egzempliorius)) ( 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 = Begalybė;< 1: this.INDEX + 1 >tai.ilgis; ); MiniDaemon.prototype.synchronize = funkcija () ( if (this.PAUSED) ( return; ) clearInterval(this.SESSION); this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this); ); MiniDaemon.prototype.pause = funkcija () ( clearInterval(this.SESSION); this.PAUSED = true; ); MiniDaemon.prototype.start = funkcija (bReverse) ( var bBackw = Būlio (bReverse); if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) ( return; ) this.BACKW = bBackw; tai.PAUSED = false this.synchronize();

MiniDaemon perduoda argumentus atgalinio skambinimo funkcijai. Jei norite dirbti su naršyklėmis, kurios iš esmės nepalaiko šios funkcijos, naudokite vieną iš anksčiau pasiūlytų metodų.

Sintaksė

var myDaemon = new MiniDaemon( šis objektas, atgalinis skambutis[ , norma [, ilgio]]);

Aprašymas Naudojimo pastabos

Funkcija setInterval() dažniausiai naudojama norint nustatyti vėl ir vėl vykdomų funkcijų, pvz., animacijų, delsą. Intervalą galite atšaukti naudodami WindowOrWorkerGlobalScope.clearInterval() .

Jei norite, kad jūsų funkcija būtų iškviesta vieną kartą po nurodyto vėlavimo naudokite .

Vėlavimo apribojimai

Galima įterpti intervalus; tai yra, setInterval() atgalinis skambutis gali iškviesti setInterval(), kad būtų paleistas kitas intervalas, net jei pirmasis vis dar vyksta. Siekiant sumažinti galimą poveikį, kurį tai gali turėti našumą, kai intervalai įterpiami daugiau nei penkių lygių gylyje, naršyklė automatiškai taikys mažiausią 4 ms vertę.

Tam tikromis aplinkybėmis naršyklės gali taikyti dar griežtesnes minimalias intervalo vertes, nors tai neturėtų būti įprasta. Taip pat atkreipkite dėmesį, kad tikrasis laikas, praeinantis tarp skambučių į atgalinį ryšį, gali būti ilgesnis nei nurodyta delsa; pavyzdžius žr. Priežastys, dėl kurių vėluojama ilgiau nei nurodyta WindowOrWorkerGlobalScope.setTimeout().

Įsitikinkite, kad vykdymo trukmė yra trumpesnė nei intervalo dažnis

Jei yra tikimybė, kad logikos vykdymas gali užtrukti ilgiau nei intervalo laikas, rekomenduojama rekursyviai iškviesti pavadintą funkciją naudojant setTimeout() . Pavyzdžiui, jei nuotolinio serverio apklausai kas 5 sekundes naudojate setInterval(), tinklo delsa, nereaguojantis serveris ir daugybė kitų problemų gali neleisti užklausai įvykdyti per numatytą laiką. Todėl galite susidurti su XHR užklausomis, kurios nebūtinai grįš tvarkingai.

Programuojant skriptų kalbomis, periodiškai reikia sukurti pauzę – kuriam laikui pristabdyti programos vykdymą, o tada tęsti darbą. Pavyzdžiui, VBS ir PHP scenarijuose galimi šie metodai:

VBS: wscript.sleep 1500 (sustabdykite 1,5 sekundės)

PHP: miegas (10); (sustabdyti 10 sekundžių)

Tokių pauzių metu vykdymo sistema (PHP arba VBS) nieko nedaro. Kūrėjas, bandantis intuityviai naudoti kažką panašaus „Javascript“, bus nemaloniai nustebintas. Dažna klaida bandant sukurti pauzę „Javascript“, atrodo taip:

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

Manote, kad kai ciklo metu ateis eilė brėžti kitą skaičių, jūsų setTimeout sąžiningai sustabdys Javascript veikimą, palaukite 0,9 sekundės, įvesties lauko gale pridės norimą skaičių ir tęs darbą. Tačiau iš tikrųjų taip nėra: setInterval ir setTimeout Javascript tik atideda skliausteliuose nurodyto veiksmo (arba funkcijos) vykdymą. Mūsų pavyzdyje atsitiks taip:

  • i = 1;
  • atidėti 0,9 sekundės skaičiaus „1“ įtraukimą į įvesties lauką;
  • Iš karto po šios problemos nustatymo ciklas tęsiasi: i=2;
  • atidėti 0,9 sekundės skaičiaus „2“ įtraukimą į įvesties lauką;
  • Iškart reiškia, pavyzdžiui, 1 ms (tai yra neproporcingai maža, palyginti su 900 ms): ciklas atliks savo darbą beveik akimirksniu, sukurdamas kelias atidėtas užduotis iš to paties momento. Tai reiškia, kad visos laukiančios „piešimo“ užduotys bus baigtos beveik tuo pačiu metu, be pertraukų tarp naujų skaičių pridėjimo. Prasideda ciklas; viskas užšąla 0,9 s; ir shirr – visi skaičiai šaudomi iš eilės vienas po kito.

    Kaip tokiu atveju teisingai pritaikyti setTimeout? Tai sudėtinga. Turėsite iškviesti funkciją rekursyviai(iš funkcijos ta pati funkcija) ir kad šis procesas nebūtų begalinis, nustatykite sustabdymo sąlygą (pvz., spausdinamo numerio dydį):

    Funkcija welltest() ( if (t. y< 9) { document.getElementById("test2").value += ++i window.setTimeout("welltest()", 400) } }

    Ir kintamasis i turės būti inicijuotas už funkcijos ribų, pavyzdžiui, taip:

    Dabar viskas veikia kaip priklauso (uždelsimo laiką sumažinome nuo 0,9 s iki 0,4 s). Tačiau tokioms užduotims logiškiau naudoti setInterval, o ne setTimeout (nors tam reikės dviejų funkcijų):

    Funkcija besttest() ( window.i = 0 window.timer1 = window.setInterval("draw()", 400) ) funkcija draw() ( document.getElementById("test3").value += ++i if (i >= 9) ClearInterval(langas.laikmatis1) )

    Javascirpt setInterval metodo ypatumas yra tas, kad jis nepraeina „savaime“ jį reikia sustabdyti specialiu clearInterval metodu. O kad būtų aišku, ką tiksliai sustabdyti, užduočiai atidėtam veiksmui priskiriamas specialus identifikatorius – laikmatis: window.timer1 = window.setInterval(...) .

    Identifikatorius taip pat galima priskirti užduotims, sukurtoms setTimeout metodu. Visi laikmačio ID turi skirtis vienas nuo kito (unikalus esamame naršyklės lange). Tada lange galite sukurti keletą skirtingų užduočių, kurios naudoja atidėtus veiksmus, ir šios užduotys bus vykdomos lygiagrečiai (kaip vienu metu, jei kompiuteryje yra pakankamai resursų), o tai iš esmės neįmanoma PHP ar VBS.

    Štai puslapio, kuriame vienu metu veikia keli „Javascript“ laikmačiai, pavyzdys: setinterval.htm (Javascript funkcijos rinkmenoje setinterval.js). Visus puslapių laikmačius (išskyrus meniu) galima sustabdyti naudojant Esc klavišą. Visi laikmačių pavyzdžiai yra pagrįsti „natūraliu“ (o ne abstrakčiu i++) atgaline atskaita – laiku arba atstumu. Visi „laikrodžiai“ yra specialiai desinchronizuoti (aiškumo dėlei). Nuo atstumo priklausomi laikmačiai naudojami „indikatoriuje“ ir išskleidžiamajame („ištraukiamas“) meniu.

    Išskleidžiamasis meniu

    Mūsų stumdomas meniu iš tikrųjų yra slenkantis (iš po „antraštės“): tarp elementų yra specialiai palikti tarpai, kad matytumėte, kaip jis išslysta. Netikėtai paaiškėjo, kad skirtingo ilgio sąrašams išėjimo nepavyko padaryti vienodai sklandaus – tikriausiai dėl mažo kompiuterio našumo (AMD Athlon 999 MHz).

    Visiškai akivaizdu, kad grožiui ir harmonijai būtina, kad skirtingų meniu punktų sąrašai atsirastų vienu metu. Tai reiškia, kad ilgesni sąrašai turėtų iškristi su daugiau didelis greitis, trumpesni - mažesniu greičiu. Atrodytų, kad tai būtų galima įgyvendinti taip:

  • Pavyzdžiui, nustatome bendrą „išvykimo“ laiką iki 200 ms.
  • Jei išskleidžiamojo sąrašo aukštis yra 20 px, akivaizdu, kad galime jį perkelti vienu pikseliu žemyn per 10 ms intervalą – tada po 200 ms išeis visas sąrašas.
  • Jei išskleidžiamasis meniu yra 40 pikselių aukščio, kad tilptų į tiek pat laiko, turime jį perkelti vienu pikseliu žemyn kas 5 ms.
  • Pagal šią logiką, jei išskleidžiamasis sąrašas yra 200 pikselių aukščio, turėtume jį perkelti vienu pikseliu žemyn kas 1 ms. Bet toks greitis mūsų kompiuteryje neveikia – naršyklė tiesiog nespėja per vieną milisekundę nupiešti naujos sąrašo padėties. Taip. Javascript sugeba suskaičiuoti (ką čia skaičiuoti?), bet naršyklė (Firefox) neturi laiko rodyti. Tipiška žiniatinklio situacija.

    Todėl daugiau ar mažiau suvienodinti meniu išvykimo laiką galima tik ramentų pagalba, o kaip tai veiks daugiau, kol kas neaišku greitas kompiuteris. Bet turėtume pasikliauti lėčiausiu, tiesa? Algoritmas (neatsižvelgiant į kompiuterio greitį) pasirodo maždaug toks:

  • Nustatykite bendrą sąrašo tikrinimo laiką: laikas = 224 (ms).
  • Nustatome minimalų vieno intervalo laiką cikle: delsa = 3 (ms).
  • Nustatykite mažiausią sąrašo perkėlimo žingsnį: poslinkis = 1 (px).
  • Visa tai keičiame priklausomai nuo sąrašo aukščio: 1) padidiname vėlavimo (intervalo) laiką atvirkščiai proporcingai aukščiui ir tiesiogiai proporcingai bendram laiko laikui (224 aukštyje koeficientas yra 1); 2) jei aukštis didesnis nei 40 px, proporcingai ūgiui padidinti minimalų žingsnį. Konstanta „40“ buvo gauta eksperimentiniu būdu lėčiausiam kompiuteriui. Testai Pentium 4 CPU 2,53GHz kompiuteriu atskleidė lygiai tokį patį skaičių – 40. Priešingu atveju laikmačiai išeina iš rikiuotės, sąrašai neveikia.
  • Dabar sąrašai daugiau ar mažiau pasirodo. Daugiau ar mažiau panašiam laikui. Puslapyje setinterval.htm.

    Ir štai Bruce'as:

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

    Pati funkcija, kuri išstumia įdėtus sąrašus iš meniu, kaip matome, yra labai paprasta. Belieka jį paleisti naudojant kažką panašaus į šią eilutę:

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

    Na, prieš pradėdami, tiesiog apskaičiuokite visus šiuos maxtop ir poslinkius, taip pat įtraukite sąrašą į mintop poziciją. Štai ką daro 40 eilučių „preliminari“ skaidrė () funkcija. Ir viskas kartu – faile setinterval.js. Taip, ir šis šūdas visai neveiks be įtraukto stilių failo

    Labai svarbu suprasti, kaip veikia JavaScript laikmačiai. Dažnai jų elgesys nesutampa su mūsų intuityviu supratimu apie daugiagiją, ir taip yra dėl to, kad iš tikrųjų jie vykdomi vienoje gijoje. Pažvelkime į keturias funkcijas, kuriomis galime valdyti laikmačius:

    • var id = setTimeout(fn, delsa); - Sukuria paprastą laikmatį, kuris iškvies tam tikrą funkciją po tam tikro delsos. Funkcija grąžina unikalų ID, su kuriuo galima pristabdyti laikmatį.
    • var id = setInterval(fn, delsa); - Panašus į setTimeout, bet nuolat iškviečia funkciją tam tikru intervalu (iki sustabdymo).
    • clearInterval(id);, clearTimeout(id); - Priima laikmačio ID (grąžina viena iš aukščiau aprašytų funkcijų) ir sustabdo atgalinio skambinimo vykdymą"a.
    Pagrindinė mintis, į kurią reikia atsižvelgti, yra ta, kad laikmačio delsos laikotarpio tikslumas nėra garantuotas. Pirmiausia naršyklė vykdo visus asinchroninius „JavaScript“ įvykius vienoje gijoje (pvz., pelės paspaudimus ar laikmačius) ir tik tuo metu, kai ateina to įvykio eilė. Tai geriausiai parodo ši diagrama:

    Šiame paveiksle yra gana daug informacijos, tačiau ją supratę galėsite geriau suprasti, kaip veikia „JavaScript“ asinchronija. Ši diagrama rodo laiką vertikaliai milisekundėmis, mėlyni blokai rodo įvykdytus JavaScript kodo blokus. Pavyzdžiui, pirmasis blokas vidutiniškai įvykdomas per 18 ms, pelės paspaudimas blokuoja vykdymą maždaug 11 ms ir t.

    „JavaScript“ gali vykdyti tik vieną kodo dalį (dėl vienos gijos vykdymo pobūdžio), kurių kiekvienas blokuoja kitų asinchroninių įvykių vykdymą. Tai reiškia, kad kai įvyksta asinchroninis įvykis (pvz., pelės paspaudimas, laikmačio iškvietimas arba XMLHttp užklausos užbaigimas), jis įtraukiamas į eilę ir vykdomas vėliau (įdiegimas, žinoma, skiriasi priklausomai nuo naršyklės, bet susitarkime vadinkite tai „eile“).

    Pirmiausia įsivaizduokime, kad „JavaScript“ bloke paleidžiami du laikmačiai: setTimeout su 10 ms vėlavimu ir setInterval su tuo pačiu vėlavimu. Priklausomai nuo to, kada įsijungs laikmatis, jis įsijungs tuo metu, kai dar neužbaigsime pirmojo kodo bloko. Tačiau atkreipkite dėmesį, kad jis neužsidega iš karto (tai neįmanoma dėl vieno sriegio). Vietoj to, atidėta funkcija įtraukiama į eilę ir vykdoma kitą galimą momentą.

    Be to, vykdant pirmąjį „JavaScript“ bloką, įvyksta pelės paspaudimas. Šio asinchroninio įvykio (ir jis yra asinchroninis, nes negalime jo numatyti) tvarkyklės šiuo metu negali būti vykdomos iš karto, todėl jis taip pat patenka į eilę, kaip ir laikmatis.

    Įvykdžius pirmąjį JavaScript kodo bloką, naršyklė užduoda klausimą: „Kas laukia, kol bus įvykdytas? IN šiuo atveju Pelės paspaudimo tvarkyklė ir laikmatis yra laukiančios būsenos. Naršyklė pasirenka vieną iš jų (paspaudimų tvarkyklę) ir jį vykdo. Laikmatis lauks kitos galimos laiko dalies vykdymo eilėje.

    Atminkite, kad vykdant pelės paspaudimų tvarkyklę suaktyvinamas pirmasis intervalinis atgalinis iškvietimas. Kaip ir laikmatis-atskambinimas, jis bus eilėje. Tačiau atminkite, kad vėl suaktyvinus intervalą (kai veikia laikmatis-atskambinimas), jis bus pašalintas iš eilės. Jei visi intervaliniai atgaliniai iškvietimai būtų įrašyti į eilę, kai vykdoma didelė kodo dalis, lauktų daugybė funkcijų, kurių vykdymas nebus atidėtas liko eilėje, prieš įtraukdami į eilę kitą.

    Taigi galime stebėti atvejį, kai trečiasis intervalo-atšaukimo paleidimas sutampa su momentu, kai jis jau įvykdomas. Tai iliustruoja svarbų dalyką: intervalams nesvarbu, kas šiuo metu veikia, jie bus įtraukti į eilę neatsižvelgiant į vėlavimo laikotarpį tarp vykdymų.

    Galiausiai, kai baigsis antrasis intervalinis atgalinis skambutis, pamatysime, kad „JavaScript“ varikliui nebelieka nieko vykdyti. Tai reiškia, kad naršyklė vėl laukia naujų asinchroninių įvykių. Tai įvyks ties 50 ms žyma, kai vėl veiks intervalinis atgalinis skambutis. Šiuo metu nebus nieko, kas jį blokuotų, todėl jis veiks nedelsiant.

    Pažvelkime į pavyzdį, kuris puikiai iliustruoja skirtumą tarp setTimeout ir setInterval.
    setTimeout(function())( /* Kažkoks ilgas kodo blokas... */ setTimeout(arguments.callee, 10); ), 10);
    setInterval(function())( /* Kažkoks ilgas kodo blokas... */ ), 10);

    Šie du variantai iš pirmo žvilgsnio yra lygiaverčiai, tačiau iš tikrųjų taip nėra. Kodas naudojant setTimeout visada turės mažiausiai 10 ms delsą po ankstesnio skambučio (gali būti daugiau, bet niekada mažiau), o kodas naudojant setInterval bus linkęs iškviesti kas 10 ms, neatsižvelgiant į tai, kada įvyko ankstesnis skambutis.
    Apibendrinkime viską, kas pasakyta aukščiau:
    - Funkcijos setTimeout ir setInterval asinchroniniame kode vykdomos iš esmės skirtingai,
    - Jei laikmačio negalima įjungti šiuo metu, jis bus atidėtas iki kito vykdymo taško (kuris bus ilgesnis nei pageidaujamas vėlavimas),
    - Intervalai (setInterval) gali būti vykdomi vienas po kito be uždelsimo, jei jų vykdymas užtrunka ilgiau nei nurodyta delsa.

    Visa tai nepaprastai svarbi informacija plėtrai. Žinant, kaip veikia „JavaScript“ variklis, ypač esant daugybei asinchroninių įvykių (kas dažnai nutinka), yra puikus pagrindas kurti pažangias programas.

    Šaltinis: http://learn.javascript.ru/settimeout-setinterval

    Beveik visi „JavaScript“ diegimai turi vidinį laikmačio planuoklį, leidžiantį suplanuoti funkciją, kuri bus iškviesta po nurodyto laiko.

    Visų pirma, ši funkcija palaikoma naršyklėse ir Node.JS serveryje.

    setTimeout

    Sintaksė:

    var timerId = setTimeout(funkcija/kodas, delsa[, arg1, arg2...])

    Parametrai:

    • funkcija / kodas
      • Funkcija arba kodo eilutė, kurią reikia vykdyti.
      • Eilutė palaikoma suderinamumui ir nerekomenduojama.
    • func
      • Vėlavimas milisekundėmis, 1000 milisekundžių yra lygus 1 sekundei.
    • arg1, arg2…
      • Argumentai perduoti funkcijai. Nepalaikomas IE9-.
      • Funkcija bus vykdoma praėjus delsos parametre nurodytam laikui.

    Pavyzdžiui, šis kodas suaktyvins įspėjimą („Sveiki“) po vienos sekundės:

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

    Jei pirmasis argumentas yra eilutė, tada interpretatorius iš tos eilutės sukuria anoniminę funkciją.

    Tai reiškia, kad šis įrašas veikia lygiai taip pat:

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

    Vietoj to naudokite anonimines funkcijas:

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

    Funkcijos ir konteksto parametrai

    Visuose šiuolaikinės naršyklės Atsižvelgiant į IE10, setTimeout leidžia nurodyti funkcijos parametrus.

    Toliau pateiktame pavyzdyje visur, išskyrus IE9-, bus išvesta „Sveiki, aš Vasya“:

    function sayHi (who) ( alert("Sveiki, aš " + kas); ) setTimeout(sayHi, 1000 , "Vasya" );

    ...Tačiau daugeliu atvejų mums reikia paramos iš senosios IE, ir ji neleidžia nurodyti argumentų. Todėl, norėdami juos perkelti, jie įtraukia skambutį į anoniminę funkciją:

    function sayHi (who) ( alert("Sveiki, aš " + kas); ) setTimeout(function () ( sayHi("Vasya") ), 1000 );

    Iškvietus setTimeout šis kontekstas nepraeina.

    Visų pirma, objekto metodo iškvietimas per setTimeout veiks pasauliniame kontekste. Tai gali lemti neteisingus rezultatus.

    Pavyzdžiui, po vienos sekundės iškvieskime user.sayHi().

    function Vartotojo (id) funkcija () ( alert(this .id); ); ) var user = new User(12345); setTimeout(user.sayHi, 1000 ); // tikimasi 12345, bet išves "undefined"

    Kadangi setTimeout vykdys funkciją user.sayHi pasauliniame kontekste, ji neturės prieigos prie objekto per šį .

    Kitaip tariant, šie du iškvietimai setTimeout atlieka tą patį:

    // (1) viena eilutė setTimeout(user.sayHi, 1000 ); // (2) tas pats dalykas dviejose eilutėse var func = user.sayHi; setTimeout(func, 1000 );

    Laimei, ši problema taip pat lengvai išsprendžiama sukuriant tarpinę funkciją:

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

    Įvyniojimo funkcija naudojama perduoti argumentus tarp naršyklių ir išsaugoti vykdymo kontekstą.

    Vykdymo atšaukimas

    Funkcija setTimeout grąžina timerId, kurį galima naudoti veiksmui atšaukti.

    Sintaksė:

    ClearTimeout (laikmačio ID)

    Šiame pavyzdyje nustatėme skirtąjį laiką ir ištryname (persigalvojome). Dėl to nieko neįvyksta.

    var timerId = setTimeout(function () ( alert(1) ), 1000 ); clearTimeout(laikmačio ID); setInterval

    Metodo setInterval sintaksė panaši į setTimeout.

    var timerId = setInterval(funkcija/kodas, delsa[, arg1, arg2...])

    Argumentų prasmė ta pati. Tačiau, skirtingai nei setTimeout , ji nevykdo funkcijos vieną kartą, o pakartoja ją reguliariai tam tikru laiko intervalu. Vykdymą sustabdyti galite paskambinę:

    ClearInterval (laikmačio ID)

    Šis pavyzdys, kai vykdomas, kas dvi sekundes rodys pranešimą, kol spustelėsite mygtuką Sustabdyti:

    var i = 1;

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

    Skambučių sudarymas eilėje ir perdengimas setInterval

    Iškvietimas setInterval(funkcija, delsa) lemia, kad funkcija bus vykdoma nurodytu laiko intervalu. Tačiau čia yra subtilumų.

    Tiesą sakant, pauzė tarp skambučių yra mažesnė nei nurodytas intervalas.

    Tai reiškia, kad naršyklė kas 100 ms tvarkingai inicijuoja funkcijos paleidimą, neatsižvelgdama į pačios funkcijos vykdymo laiką.

    Pasitaiko, kad funkcijos vykdymas užtrunka ilgiau nei delsimas. Pavyzdžiui, funkcija sudėtinga, bet delsimas mažas. Arba funkcijoje yra įspėjimo / patvirtinimo / raginimo teiginių, kurie blokuoja vykdymo giją. Čia viskas pradeda įdomėti.

    Jei funkcijos negalima paleisti, nes naršyklė užimta, ji bus įtraukta į eilę ir bus vykdoma, kai tik naršyklė bus laisva.

    Toliau pateiktame paveikslėlyje parodyta, kas nutinka funkcijai, kuriai vykdyti reikia daug laiko.

    Funkcijos iškvietimas, inicijuotas setInterval, įtraukiamas į eilę ir įvyksta nedelsiant, kai įmanoma:

    Antrasis funkcijos paleidimas įvyksta iškart po pirmosios:

    Vykdymas nėra eilėje daugiau nei vieną kartą.

    Jei funkcijos vykdymas užtrunka ilgiau nei keli suplanuoti vykdymai, ji vis tiek atsidurs eilėje vieną kartą. Taigi nėra paleidimo „kaupimo“.

    Žemiau esančiame paveikslėlyje setInterval bando įvykdyti funkciją per 200 ms ir nustato skambučio eilę. Po 300 ms ir 400 ms laikmatis vėl atsibunda, bet nieko neįvyksta.

    SetInterval (funkcija, delsa) iškvietimas negarantuoja faktinio vėlavimo tarp vykdymų.

    Pasitaiko atvejų, kai realus vėlavimas yra didesnis arba mažesnis nei nurodytas. Apskritai, tai nėra faktas, kad bus bent šiek tiek vėlavimo.

    Kartojamas įdėtas setTimeout

    Tais atvejais, kai reikia ne tik reguliaraus kartojimo, bet ir uždelsimo tarp paleidimų, setTimeout naudojamas iš naujo nustatyti kiekvieną kartą, kai funkcija vykdoma.

    Toliau pateikiamas pavyzdys, kuris pateikia įspėjimą su 2 sekundžių intervalais.

    var i = 1;

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

    Vykdymo laiko juostoje bus nustatytos uždelsos tarp paleidimų. 100 ms vėlavimo iliustracija:

    Minimali laikmačio delsa

    Naršyklės laikmatis turi mažiausią galimą delsą. Šiuolaikinėse naršyklėse jis svyruoja nuo maždaug nulio iki 4 ms. Senesniuose jis gali būti ilgesnis ir siekti 15 ms.

    Pagal standartą minimalus vėlavimas yra 4 ms. Taigi nėra skirtumo tarp setTimeout(..,1) ir setTimeout(..,4).

  • Nulinės delsos setTimeout ir setInterval elgesys priklauso nuo naršyklės.
  • Internet Explorer programoje zero delay setInterval(.., 0) neveiks. Tai konkrečiai taikoma setInterval , t.y. setTimeout (.., 0) veikia gerai.
  • Faktinis paleidimo dažnis

    Suveikimas gali būti daug retesnis Kai kuriais atvejais vėlavimas gali būti ne 4 ms, o 30 ms ar net 1000 ms.

    Dauguma naršyklių (visų pirma darbalaukio) ir toliau vykdo setTimeout / setInterval, net jei skirtukas neaktyvus. Tuo pačiu metu kai kurie iš jų (Chrome, FF, IE10) sumažina minimalų laikmačio dažnį iki 1 karto per sekundę. Pasirodo, laikmatis veiks „fono“ skirtuke, bet retai.

    Kai naudojate akumuliatoriaus energiją, nešiojamajame kompiuteryje naršyklės taip pat gali sumažinti dažnį, kad kodą vykdytų rečiau ir taupytų akumuliatoriaus energiją. IE tuo ypač garsėja. Priklausomai nuo nustatymų, sumažinimas gali siekti kelis kartus. Jei procesoriaus apkrova per didelė, „JavaScript“ gali nesugebėti laiku apdoroti laikmačių. Taip bus praleisti kai kurie „setInterval“ paleidimai.

    Išvada: verta sutelkti dėmesį į 4 ms dažnį, tačiau neturėtumėte to tikėtis.

    Intervalų išvedimas į konsolę Kodas, skaičiuojantis laiko intervalus tarp skambučių, atrodo maždaug taip:

    var timeMark = nauja data; setTimeout(function go () ( var diff = new Data - timeMark; // spausdinkite kitą delsą konsolėje vietoj puslapio konsolės .log(diff); // prisiminkite laiką pačioje pabaigoje, // norėdami išmatuoti delsa tarp skambučių timeMark = new Date ; setTimeout(go, 100 ), 100 ); Triukas yra setTimeout(func, 0)

    Šis triukas vertas patekti į „JavaScript“ įsilaužimų metraštį.

    Funkcija suvyniota į setTimeout(func, 0), jei norite ją paleisti pasibaigus dabartiniam scenarijui.

    Reikalas tas, kad setTimeout niekada nevykdo funkcijos iš karto. Jis tik planuoja jos įgyvendinimą. Tačiau „JavaScript“ interpretatorius pradės vykdyti numatytas funkcijas tik tada, kai bus vykdomas dabartinis scenarijus.

    Pagal standartą setTimeout vis tiek negali vykdyti funkcijos su 0 uždelsimu. Kaip minėjome anksčiau, uždelsimas paprastai yra 4 ms. Bet svarbiausia čia yra tai, kad vykdymas bet kokiu atveju vyks po dabartinio kodo vykdymo.

    Pavyzdžiui:

    var rezultatas; funkcija showResult () ( alert(result); ) setTimeout(showResult, 0 ); rezultatas = 2 *2 ; // išves 4 Total

    SetInterval(func, delay) ir setTimeout(func,delay) metodai leidžia paleisti func reguliariai/kartą per delsos milisekundes.

    Abu metodai grąžina laikmačio ID. Jis naudojamas sustabdyti vykdymą iškviečiant clearInterval / clearTimeout .

    | | setInterval | setTimeout | || ----------- | ----------- | | Laikas | Skambutis yra griežtai pagal laikmatį. Jei vertėjas užimtas, vienas skambutis yra eilėje. Į funkcijos vykdymo laiką neatsižvelgiama, todėl laiko intervalas nuo vieno paleidimo pabaigos iki kito pradžios gali skirtis. | Rekursyvus setTimeout iškvietimas naudojamas vietoj setInterval, kai reikia fiksuotos pauzės tarp vykdymų. | | Vėlavimas | Minimalus delsimas: 4ms. | Minimalus delsimas: 4ms. | | Naršyklės funkcijos | Latencija 0 neveikia IE | „Opera“ nulinis delsos laikas yra lygus 4 ms, o kiti vėlavimai apdorojami tiksliai, įskaitant nestandartinius 1 ms, 2 ms ir 3 ms. |

    © 2024 ermake.ru - Apie kompiuterių taisymą - Informacinis portalas