Window: setInterval() method
BaselineWidely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
* Some parts of this feature may have varying levels of support.
ThesetInterval()
method of theWindow
interface repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
Syntax
setInterval(code)setInterval(code, delay)setInterval(func)setInterval(func, delay)setInterval(func, delay, arg1)setInterval(func, delay, arg1, arg2)setInterval(func, delay, arg1, arg2, /* …, */ argN)
Parameters
func
A
function
to be executed everydelay
milliseconds. The first execution happens afterdelay
milliseconds.code
An optional syntax allows you to include a string instead of a function, which is compiled and executed every
delay
milliseconds.This syntax isnot recommended for the same reasons that make usingeval()
a security risk.delay
OptionalThe time, in milliseconds (thousandths of a second), the timer should delay in between executions of the specified function or code. Defaults to 0 if not specified.SeeDelay restrictions below for details on the permitted range of
delay
values.arg1
, …,argN
OptionalAdditional arguments which are passed through to the function specified byfunc once the timer expires.
Return value
ThesetInterval()
method returns a positive integer (typically within the range of 1 to 2,147,483,647) that uniquely identifies the interval timer created by the call. This identifier, often referred to as an "interval ID", can be passed toclearInterval()
to stop the repeated execution of the specified function.
Within the same global environment (e.g., a particular window or worker), the interval ID is ensured to remain unique and is not reused for any new interval timer as long as the original timer is still active. However, different global environments maintain their own independent pools of interval IDs.
Be aware thatsetInterval()
andsetTimeout()
share the same pool of IDs, and thatclearInterval()
andclearTimeout()
can technically be used interchangeably.For clarity, however, you should try to always match them to avoid confusion when maintaining your code.
Note:Thedelay
argument is converted to a signed 32-bit integer.This effectively limitsdelay
to 2147483647 ms, roughly 24.8 days, since it's specified as a signed integer in the IDL.
Examples
Example 1: Basic syntax
The following example demonstratessetInterval()
's basic syntax.
const intervalID = 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 theflashtext()
function once a second untilthe Stop button is pressed.
HTML
<div> <h3>Hello World</h3></div><button>Start</button><button>Stop</button>
CSS
.go { color: green;}.stop { color: red;}
JavaScript
// variable to store our intervalIDlet intervalId;function changeColor() { // check if an interval has already been set up intervalId ??= setInterval(flashText, 1000);}function flashText() { const oElem = document.getElementById("my_box"); oElem.className = oElem.className === "go" ? "stop" : "go";}function stopTextColor() { clearInterval(intervalId); // release our intervalId from the variable intervalId = null;}document.getElementById("start").addEventListener("click", changeColor);document.getElementById("stop").addEventListener("click", stopTextColor);
Result
The "this" problem
When you pass a method tosetInterval()
or any other function, it is invoked with the wrongthis
value.This problem is explained in detail in theJavaScript reference.
Explanation
Code executed bysetInterval()
runs in a separate execution context thanthe function from which it was called. As a consequence, thethis
keyword for the called function is set to thewindow
(orglobal
) object, it is not the same as thethis
value for thefunction that calledsetTimeout
. See the following example (which usessetTimeout()
instead ofsetInterval()
– the problem, in fact,is the same for both timers):
myArray = ["zero", "one", "two"];myArray.myMethod = function (sProperty) { alert(arguments.length > 0 ? this[sProperty] : this);};myArray.myMethod(); // prints "zero,one,two"myArray.myMethod(1); // prints "one"setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 secondsetTimeout(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 thethis
object to the callbackfunction in the legacy JavaScript.
A possible solution
All modern JavaScript runtimes (in browsers and elsewhere) supportarrow functions, with lexicalthis
— allowing us to writesetInterval(() => this.myMethod())
if we're inside themyArray
method.
If you need to support IE, use theFunction.prototype.bind()
method, which lets you specify the value that should be used asthis
for all calls to a given function. That lets you easily bypass problems where it's unclear whatthis
will be, depending on the context from which your function was called.
Usage notes
ThesetInterval()
function is commonly used to set a delay for functionsthat are executed again and again, such as animations. You can cancel the interval usingclearInterval()
.
If you wish to have your function calledonce after the specified delay, usesetTimeout()
.
Delay restrictions
It's possible for intervals to be nested; that is, the callback forsetInterval()
can in turn callsetInterval()
to start anotherinterval running, even though the first one is still going. To mitigate the potentialimpact 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. Attemptsto specify a value less than 4 ms in deeply-nested calls tosetInterval()
will be pinned to 4 ms.
Browsers may enforce even more stringent minimum values for the interval under somecircumstances, although these should not be common. Note also that the actual amount oftime that elapses between calls to the callback may be longer than the givendelay
; seeReasons for delays longer than specified 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 theinterval time, it is recommended that you recursively call a named function usingsetTimeout()
. For example, ifusingsetInterval()
to poll a remote server every 5 seconds, networklatency, an unresponsive server, and a host of other issues could prevent the requestfrom completing in its allotted time. As such, you may find yourself with queued up XHRrequests that won't necessarily return in order.
In these cases, a recursivesetTimeout()
pattern is preferred:
(function loop() { setTimeout(() => { // Your logic here loop(); }, delay);})();
In the above snippet, a named functionloop()
is declared and isimmediately executed.loop()
is recursively called insidesetTimeout()
after the logic has completed executing. While this patterndoes not guarantee execution on a fixed interval, it does guarantee that the previousinterval has completed before recursing.
Specifications
Specification |
---|
HTML # dom-setinterval-dev |