The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval() . This method is defined by the WindowOrWorkerGlobalScope mixin.

Syntax var intervalID = scope.setInterval( func, delay, [arg1, arg2, ...]); var intervalID = scope.setInterval( code, delay); Parameters func A function to be executed every delay milliseconds. The function is not passed any arguments, and no return value is expected. code An optional syntax allows you to include a string instead of a function, which is compiled and executed every delay milliseconds. This syntax is not recommended for the same reasons that make using eval() a security risk. delay The time, in milliseconds (thousandths of a second), the timer should delay in between executions of the specified function or code. See below for details on the permitted range of delay values. arg1, ..., argN Optional Additional arguments which are passed through to the function specified by func once the timer expires.

Note : Passing additional arguments to setInterval() in the first syntax does not work in Internet Explorer 9 and earlier. If you want to enable this functionality on that browser, you must use a polyfill (see the section).

Return value

The returned intervalID is a numeric, non-zero value which identifies the timer created by the call to setInterval() ; this value can be passed to cancel the timeout.

It may be helpful to be aware that setInterval() and setTimeout() share the same pool of IDs, and that clearInterval() and clearTimeout() can technically be used interchangeably. For clarity, however, you should try to always match them to avoid confusion when maintaining your code.

Note: The delay argument is converted to a signed 32-bit integer. This effectively limits delay to 2147483647 ms, since it"s specified as a signed integer in the IDL.

Examples Example 1: Basic syntax

The following example demonstrates setInterval() "s basic syntax.

Var intervalID = window.setInterval(myCallback, 500, "Parameter 1", "Parameter 2"); function myCallback(a, b) ( // Your code here // Parameters are purely optional. console.log(a); console.log(b); )

Example 2: Alternating two colors

The following example calls the flashtext() function once a second until the Stop button is pressed.

setInterval/clearInterval example 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" is a ternary operator. ) function stopTextColor() ( clearInterval(nIntervId); )

Hello World

Stop

Example 3: Typewriter simulation

The following example simulates typewriter by first clearing and then slowly typing content into the NodeList that matches a specified group of selectors.

JavaScript Typewriter - MDN Example function Typewriter (sSelector, nRate) ( function clean () ( clearInterval(nIntervId); bTyping = false; bStart = true; oCurrent = null; aSheets.length = nIdx = 0; ) function scroll (oSheet, nPos , bEraseAndStop) ( if (!oSheet.hasOwnProperty("parts") || aMap.length< 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; */ }

CopyLeft 2012 by Mozilla Developer Network

[ Play | Pause | Terminate]

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 Typewriter

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ultrices dolor ac dolor imperdiet ullamcorper. Suspendisse quam libero, luctus auctor mollis sed, malesuada condimentum magna. Quisque in ante tellus, in placerat est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec a mi magna, quis mattis dolor. Etiam sit amet ligula quis urna auctor imperdiet nec faucibus ante. Mauris vel consectetur dolor. Nunc eget elit eget velit pulvinar fringilla consectetur aliquam purus. Curabitur convallis, justo posuere porta egestas, velit erat ornare tortor, non viverra justo diam eget arcu. Phasellus adipiscing fermentum nibh ac commodo. Nam turpis nunc, suscipit a hendrerit vitae, volutpat non ipsum.

Phasellus ac nisl lorem:
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 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 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.

Callback arguments

As previously discussed, Internet Explorer versions 9 and below do not support the passing of arguments to the callback function in either setTimeout() or setInterval() . The following IE-specific code demonstrates a method for overcoming this limitation. To use, simply add the following code to the top of your script.

/*\ |*| |*| IE-specific polyfill that enables the passage of arbitrary arguments to the |*| callback functions of javascript timers (HTML5 standard syntax)..setInterval |*| https://site/User:fusionchess |*| |*| Syntax: |*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]); |*| var timeoutID = window.setTimeout(code, delay); |*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]); |*| var intervalID = window.setInterval(code, delay); |*| \*/ 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 ? function () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay); ); window.setTimeout.isPolyfill = true; ) if (document.all && !window.setInterval.isPolyfill) ( 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 ? function () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay); ); window.setInterval.isPolyfill = true; )

Another possibility is to use an anonymous function to call your callback, although this solution is a bit more expensive. Example:

Var intervalID = setInterval(function() ( myFunc("one", "two", "three"); ), 1000); var intervalID = setInterval(function(arg1) ().bind(undefined, 10), 1000);

Inactive tabs Requires Gecko 5.0(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)

Starting in Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), intervals are clamped to fire no more often than once per second in inactive tabs.

The "this" problem

When you pass a method to setInterval() or any other function, it is invoked with the wrong this value. This problem is explained in detail in the JavaScript reference.

Explanation

Code executed by setInterval() runs in a separate execution context than the function from which it was called. As a consequence, the this keyword for the called function is set to the window (or global) object, it is not the same as the this value for the function that called setTimeout . See the following example (which uses setTimeout() instead of setInterval() – the problem, in fact, is the same for both timers):

MyArray = ["zero", "one", "two"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); myArray.myMethod(); // prints "zero,one,two" myArray.myMethod(1); // prints "one" setTimeout(myArray.myMethod, 1000); // prints "" after 1 second setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds // passing the "this" object with .call won"t work // because this will change the value of this inside setTimeout itself // while we want to change the value of this inside myArray.myMethod // in fact, it will be an error because setTimeout code expects this to be the window object: setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object" setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error

As you can see there are no ways to pass the this object to the callback function in the legacy JavaScript.

A possible solution

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones that enable their invocation through the Function.prototype.call method. The following example shows a possible replacement:

// Enable the passage of the "this" object through the JavaScript timers var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = function (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 = function (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); );

These two replacements also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as non-standard-compliant polyfills also. See the for a standard-compliant polyfill

New feature test:

MyArray = ["zero", "one", "two"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but... setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2.5 seconds

For a more complex but still modular version of it ( Daemon) see JavaScript Daemons Management . This more complex version is nothing but a large and scalable collection of methods for the Daemon constructor. However, the Daemon constructor itself is nothing but a clone of MiniDaemon with an added support for init and onstart functions declared during the instantiation of the daemon. So the MiniDaemon framework remains the recommended way for simple animations , because Daemon without its collection of methods is essentially a clone of it.

minidaemon.js /*\ |*| |*| :: MiniDaemon:: |*| |*| Revision #2 - September 26, 2014.setInterval |*| https://site/User:fusionchess |*| https://github.com/madmurphy/minidaemon.js |*| |*| This framework is released under the GNU Lesser General Public License, version 3 or later. |*| http://www.gnu.org/licenses/lgpl-3.0.html |*| \*/ function 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; /* These properties should be read-only */ MiniDaemon.prototype.SESSION = -1; MiniDaemon.prototype.INDEX = 0; MiniDaemon.prototype.PAUSED = true; MiniDaemon.prototype.BACKW = true; /* Global methods */ MiniDaemon.forceCall = function (oDmn) ( oDmn.INDEX += oDmn.BACKW ? -1: 1; if (oDmn.task.call(oDmn.owner, oDmn.INDEX, oDmn.length, oDmn .BACKW) === false || oDmn.isAtEnd()) ( oDmn.pause(); return false; ) return true; ); /* Instances methods */ MiniDaemon.prototype.isAtEnd = function () ( return this.BACKW ? isFinite(this.length) && this.INDEX< 1: this.INDEX + 1 >this.length; ); 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 passes arguments to the callback function. If you want to work on it with browsers that natively do not support this feature, use one of the methods proposed above.

Syntax

var myDaemon = new MiniDaemon( thisObject, callback[ , rate [, length]]);

Description Usage notes

The setInterval() function is commonly used to set a delay for functions that are executed again and again, such as animations. You can cancel the interval using WindowOrWorkerGlobalScope.clearInterval() .

If you wish to have your function called once after the specified delay, use .

Delay restrictions

It"s possible for intervals to be nested; that is, the callback for setInterval() can in turn call setInterval() to start another interval running, even though the first one is still going. To mitigate the potential impact this can have on performance, once intervals are nested beyond five levels deep, the browser will automatically enforce a 4 ms minimum value for the interval. Attempts to specify a value less than 4 ms in deeply-nested calls to setInterval() will be pinned to 4 ms.

Browsers may enforce even more stringent minimum values ​​for the interval under some circumstances, although these should not be common. Note also that the actual amount of time that elapses between calls to the callback may be longer than the given delay; see Reasons for delays longer than specified in WindowOrWorkerGlobalScope.setTimeout() for examples.

Ensure that execution duration is shorter than interval frequency

If there is a possibility that your logic could take longer to execute than the interval time, it is recommended that you recursively call a named function using setTimeout() . For example, if using setInterval() to poll a remote server every 5 seconds, network latency, an unresponsive server, and a host of other issues could prevent the request from completing in its allotted time. As such, you may find yourself with queued up XHR requests that won"t necessarily return in order.

JavaScript timeout is a native javascript function that executes a piece of code after a specified time delay (in milliseconds). This can be useful when you need to display a popup after the user has spent some time on your page. Or do you want the effect when you hover over an element to start only after some time has passed? This way, you can avoid unintentionally triggering an effect if the user hovered over it accidentally.

Simple setTimeout example

To demonstrate how this feature works, I suggest taking a look at the following demo, in which a pop-up window appears two seconds after the button is clicked.

View demo

Syntax

The MDN documentation provides the following syntax for setTimeout:

var timeoutID = window.setTimeout(func, ); var timeoutID = window.setTimeout(code, );

  • timeoutID – a numeric id that can be used in combination with clearTimeout() to disable the timer;
  • func – function to be executed;
  • code (in alternative syntax) – line of code to be executed;
  • delay – the duration of the delay in milliseconds, after which the function will be launched. The default value is 0.
setTimeout vs window.setTimeout

The above syntax uses window.setTimeout . Why?

In fact, setTimeout and window.setTimeout are practically the same function. The only difference is that in the second expression we use the setTimeout method as a property of the global window object.

Personally, I think this just makes the code much more complicated. If we were to define an alternative JavaScript timeout method that could be found and returned in priority order, we would run into even more problems.

In this tutorial, I don't want to mess with the window object, but in general, it's up to you to decide which syntax to use.

Examples of using

This could be the name of the function:

function explode())( alert("Boom!"); ) setTimeout(explode, 2000);

Variable that refers to the function:

var explode = function())( alert("Boom!"); ); setTimeout(explode, 2000);

Or an anonymous function:

setTimeout(function())( alert("Boom!"); ), 2000);

  • Such code is poorly understood and, therefore, will be difficult to modernize or debug;
  • It involves the use of the eval() method, which could be a potential vulnerability;
  • This method is slower than others because it requires running the JavaScript interpreter.

Also note that we are using the JavaScript timeout alert method to test the code.

Passing parameters to setTimout

In the first (and cross-browser) option, we pass parameters to the callback function, executed using setTimeout.

In the following example, we extract a random greeting from the greetings array and pass it as a parameter to the greet() function, which is executed by setTimeout with a delay of 1 second:

function greet(greeting)( console.log(greeting); ) function getRandom(arr)( return arr; ) var greetings = ["Hello", "Bonjour", "Guten Tag"], randomGreeting = getRandom(greetings); setTimeout(function())( greet(randomGreeting); ), 1000);

View demo

Alternative method

In the syntax given at the beginning of the article, there is another method by which you can pass parameters to the callback function executed by JavaScript timeout. This method implies the output of all parameters following the delay.

Based on the previous example, we get:

setTimeout(greet, 1000, randomGreeting);

This method will not work in IE 9 and below where passed parameters are regarded as undefined . But there is a special polyfill on MDN to solve this problem.

Related problems and “this”

The code executed by setTimeout runs separately from the function that called it. Because of this, we encounter certain problems that can be solved by using the this keyword.

var person = ( firstName: "Jim", introduce: function())( console.log("Hi, I"m " + this.firstName); ) ); person.introduce(); // Outputs: Hi, I" m Jim setTimeout(person.introduce, 50); // Outputs: Hi, I"m undefined

The reason for this output is that in the first example this points to the person object, and in the second example it points to the global window object, which does not have a firstName property.

To get rid of this inconsistency, you can use several methods:

Force this to be set

This can be done using bind(), a method that creates new feature, which when called uses a specific value as the value of the this key. In our case, the specified person object. This ultimately gives us:

setTimeout(person.introduce.bind(person), 50);

Note: the bind method was introduced in ECMAScript 5, which means it will only work in modern browsers. In others, when you use it, you will receive a JavaScript execution error “function timeout error”.

Use library

Many libraries include built-in functions needed to solve the this problem. For example, the jQuery.proxy() method. It takes a function and returns a new one that will always use a specific context. In our case, the context will be:

setTimeout($.proxy(person.introduce, person), 50);

View demo

Disabling the timer

The return value of setTimeout is a numeric id that can be used to disable the timer using the clearTimeout() function:

var timer = setTimeout(myFunction, 3000); clearTimeout(timer);

Let's see it in action. In the following example, if you click on the “Start countdown” button, the countdown will begin. After it is completed, the kittens will get theirs. But if you click the “Stop countdown” button, the JavaScript timeout timer will be stopped and reset.

View example

Let's sum it up

setTimeout is an asynchronous function, which means that the resulting call to this function goes into a queue and will be executed only after all other actions on the stack have completed. It cannot run simultaneously with other functions or a separate thread.

In programming in scripting languages, there is periodically a need to create a pause - to pause the execution of the program for a while, and then continue working. For example, in VBS and PHP scripts the following methods are possible:

VBS: wscript.sleep 1500 (stop for 1.5 seconds)

PHP: sleep(10); (stop for 10 seconds)

During such pauses, the runtime system (PHP or VBS) doing nothing. A developer trying to intuitively use something similar in Javascript will be unpleasantly surprised. A typical error when trying to create a pause in Javascript looks like this:

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

Do you think that when the turn comes to drawing the next number during the loop, your setTimeout will honestly stop Javascript work, will wait 0.9 seconds, add the required number to the end of the input field and then continue working. But in reality this is not true: setInterval and setTimeout in Javascript only delay the execution of the action (or function) specified in parentheses. In our example, the following will happen:

  • i = 1;
  • delay adding the number "1" to the input field by 0.9 seconds;
  • Immediately after setting this problem, the cycle continues: i=2;
  • delay adding the number "2" to the input field by 0.9 seconds;
  • Immediately means, for example, 1 ms (that is, disproportionately small compared to 900 ms): the loop will do its work almost instantly, creating several deferred tasks from the same point in time. This means that all pending “drawing” tasks will be completed at almost the same time, without pauses between adding new numbers. The cycle starts; everything freezes for 0.9 s; and shirr - all the numbers are shot in a row one after another.

    How to correctly apply setTimeout in such a case? It's complicated. You'll have to call the function recursively(from within the function the same function), and so that this process is not endless, set a stopping condition (for example, the size of the number to be printed):

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

    And the variable i will have to be initialized outside the function - for example, like this:

    Now everything works as it should (we reduced the delay time from 0.9 s to 0.4 s). But for such tasks, it is more logical to use setInterval rather than setTimeout (although this will require two functions):

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

    The peculiarity of the Javascirpt setInterval method is that it does not pass “by itself”; it must be stopped with a special clearInterval method. And to make it clear what exactly to stop, the task for the deferred action is assigned a special identifier - a timer: window.timer1 = window.setInterval(...) .

    Identifiers can also be assigned to tasks created by the setTimeout method. All timer IDs must be distinct from each other (unique within the current browser window). Then you can create several different tasks in the window that use deferred actions, and these tasks will be executed in parallel (sort of simultaneously, if the computer has enough resources), which is basically impossible in PHP or VBS.

    Here is an example of a page with several Javascript timers running simultaneously: setinterval.htm (Javascript functions in the setinterval.js file). All page timers (except menu) can be stopped using the Esc key. All example timers are based on a “natural” (and not abstract i++) countdown - time or distance. All “clocks” are specially desynchronized (for clarity). Distance-dependent timers are used in the “indicator” and in the drop-down (“pull-out”) menu.

    Drop-down menu

    Our sliding menu is actually sliding (from under the “header”): gaps are specially left between the elements so that you can see how it slides out. Unexpectedly, it turned out that we could not make the exit equally smooth for lists of different lengths - probably due to the low performance of the computer (AMD Athlon 999 MHz).

    It is quite obvious that for beauty and harmony it is necessary that the lists of different menu items appear at the same time. That is, longer lists should drop out at a higher speed, shorter ones at a lower speed. It would seem that this could be implemented like this:

  • We set the total “departure” time, for example, to 200 ms.
  • If the dropdown list has a height of 20 px, it is obvious that we can move it down one pixel per 10 ms interval - and then in 200 ms the entire list will come out.
  • If the dropdown is 40px high, to fit in the same amount of time we have to move it down one pixel every 5ms.
  • By this logic, if the dropdown list is 200px high, we should move it down one pixel every 1ms. But such speed does not work on our computer - the browser simply does not have time to draw the new position of the list in one millisecond. Yes. Javascript manages to count (what is there to count?), but the browser (Firefox) does not have time to display. Typical situation for the web.

    Therefore, it is possible to more or less equalize the time of leaving the menu only with the help of crutches, and it is still unclear how this will work on a faster computer. But we should count on the slowest one, right? The algorithm (without taking into account the speed of the computer) turns out something like this:

  • Set the total time for checking out the list: time = 224 (ms).
  • We set the minimum time for one interval in the cycle: delay = 3 (ms).
  • Set the minimum step for moving the list: offset = 1 (px).
  • We change all this depending on the height of the list: 1) increase the delay (interval) time in inverse proportion to the height and directly proportional to the total time time (at a height of 224 the coefficient is 1); 2) if the height is greater than 40 px, increase the minimum step in proportion to the height. The constant "40" was obtained experimentally for the slowest computer. Tests on a Pentium 4 CPU 2.53GHz computer revealed exactly the same number - 40. Otherwise, timers go out of order, lists go out of step.
  • Now the lists are more or less coming out. For more or less similar time. On the setinterval.htm page.

    And here comes Bruce:

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

    The function itself, which pushes nested lists out of the menu, is, as we can see, very simple. All that remains is to run it with something like this line:

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

    Well, before starting, just calculate all these maxtop and offset, and also place the list in the mintop position. This is what the “preliminary” slide() function of 40 lines does. And all together - in the setinterval.js file. Yes, and this crap won't work at all without the included styles file

    • From:
    • Registered: 2014.07.08
    • Posts: 3,896
    • Likes: 497
    Topic: SetTimeOut and SetInterval, which is better to use in JavaScript?

    The setInterval function is designed to run code multiple times at regular intervals. However, it has a number of disadvantages, mainly different behavior in different browsers.

    The first difference is the difference in the time at which the timer is set for the next launch. Let's create a small test: we will measure the amount of time that has passed since the start of the previous run and since its end.

    var d1 = new Date(), d2 = new Date(); setInterval(function() ( var d = new Date(); document.body.innerHTML += (d - d1) + " " + (d - d2) + "
    "; // Put a mark at the beginning of the function d1 = new Date(); while (new Date() - d1< 200); // ничего не делаем 200 миллисекунд // И в конце функции d2 = new Date(); }, 1000);

    The output will be informative starting from the second line.

    In Firefox, Opera, Safari and Chrome the situation will be similar: the first number will be approximately equal to 1000, the second - 200 less. The only difference will be in the spread of values. The smallest difference is in Chrome and Opera.

    2 Reply by PunBB (edited by PunBB 2017.06.08 16:45)
    • From: Moscow, Sovkhoznay 3, apt. 98
    • Registered: 2014.07.08
    • Posts: 3,896
    • Likes: 497

    Another difference that is less noticeable and more difficult to reproduce, but can sometimes cause a lot of trouble, is resistance to system time changes. If you run the following test

    setInterval(function() ( document.body.innerHTML = Math.random(); ), 500);

    And after startup, set the system time back a minute, then to Firefox browsers and Safari, the number change will pause, and after a minute it will start again. Of course, manual translation of system time is an extremely rare situation, but many systems are configured to automatically synchronize time with servers on the Internet, so in some situations this factor cannot be discounted.

    Another small disadvantage of the setInterval function is that in order to be able to stop its action, you need to remember its identifier somewhere, which is not always convenient.

    3 Reply by PunBB
    • From: Moscow, Sovkhoznay 3, apt. 98
    • Registered: 2014.07.08
    • Posts: 3,896
    • Likes: 497
    Re: SetTimeOut and SetInterval, which is better to use in JavaScript?

    To get rid of the listed disadvantages of setInterval, you can use multiple setTimeout.

    An important alternative to setInterval is the recursive setTimeout:

    /** instead of: var timerId = setInterval(function() ( alert("tick"); ), 2000); */ var timerId = setTimeout(function tick() ( alert("tick"); timerId = setTimeout(tick, 2000); ), 2000);

    In the code above, the next execution is scheduled immediately after the previous one finishes.

    Recursive setTimeout is a more flexible timing method than setInterval, since the time until the next execution can be scheduled differently, depending on the results of the current one.

    For example, we have a service that polls the server for new data every 5 seconds. If the server is overloaded, you can increase the polling interval to 10, 20, 60 seconds... And then return it back when everything returns to normal.

    If we regularly run CPU-intensive tasks, then we can estimate the time spent on their execution and plan the next run earlier or later.

    4 Reply by PunBB
    • From: Moscow, Sovkhoznay 3, apt. 98
    • Registered: 2014.07.08
    • Posts: 3,896
    • Likes: 497
    Re: SetTimeOut and SetInterval, which is better to use in JavaScript?

    Recursive setTimeout guarantees a pause between calls, setInterval does not.

    Let's compare the two codes. The first one uses setInterval:

    var i = 1; setInterval(function() ( func(i); ), 100);

    The second one uses a recursive setTimeout:

    var i = 1; setTimeout(function run() ( func(i); setTimeout(run, 100); ), 100);

    With setInterval, the internal timer will fire exactly every 100 ms and call func(i):

    The real pause between func calls with setInterval is less than indicated in the code!

    This is natural, because the operating time of the function is not taken into account in any way; it “eats up” part of the interval.

    It is also possible that func turned out to be more complex than we expected and took longer than 100 ms to execute.

    In this case, the interpreter will wait for the function to complete, then check the timer and, if the time for calling setInterval has already come (or passed), then the next call will occur immediately.

    If the function runs longer than the setInterval pause, then calls will occur without any interruption at all.

    5 Reply by sempai
    • From: Jerusalem
    • Registered: 2015.06.02
    • Posts: 958
    • Likes: 274
    Re: SetTimeOut and SetInterval, which is better to use in JavaScript?

    It all depends on the task at hand. Initially, SetTimeOut is used to start the timer once, and SetInterval is used to start a loop. But both functions can be used to run scripts cyclically; if, for example, you run them recursively in the SetTimeOut function, then they will act almost similarly to SetInterval.

    The disadvantage of SetInterval at the moment is that it does not take into account the execution time of the script (function) itself, and if, for example, you use it for heavy queries, then the interval time will be significantly reduced, and it may differ in different browsers.

    But again, if the function or request is minimized, then the end user is unlikely to feel the difference.
    Therefore, what to use is up to everyone to decide for themselves.