setTimeout()
The setTimeout() method is used to specify that a function or string is executed after the specified number of milliseconds. It returns an integer representing the timer's number, which can be passed to clearTimeout() to cancel the execution of this function
In the following code, the console outputs 0 first, after about 1000ms, that is, 1s, the return value of the timer setTimeout() method is output.
var Timer = setTimeout(function(){console.log(Timer);},1000);console.log(0);It can also be written as string parameters. Since this form will cause the javascript engine to parse twice, reducing performance, it is not recommended to use it.
var Timer = setTimeout('console.log(Timer);',1000);console.log(0);If the second parameter of setTimeout is omitted, the parameter defaults to 0
In the following code, 0 and 1 appear on the console, but 0 is in front, and this question will be explained later.
var Timer = setTimeout(function(){console.log(Timer);});console.log(0);In fact, in addition to the first two parameters, the setTimeout() method also allows adding more parameters, which will be passed into the function in the timer.
In the following code, the console will output 2 after about 1000ms, that is, 1s. However, the IE9-browser only allows setTimeout to have two parameters, and does not support more parameters. NaN will be output on the console.
setTimeout(function(a,b){console.log(a+b);},1000,1,1);You can use IIFE parameter transfer to be compatible with IE9-browser function parameter transfer
setTimeout((function(a,b){return function(){console.log(a+b);}})(1,1),1000);Or write the function outside the timer, and then the function is called with parameters in the anonymous function in the timer.
function test(a,b){console.log(a+b);}setTimeout(function(){test(1,1);},1000);This points to
The four binding rules pointed to by this mechanism have been introduced in detail in this series. Since this in the timer is implicitly lost and is very prone to errors, it will be explained again here.
var a = 0;function foo(){console.log(this.a);};var obj = {a : 2,foo:foo}setTimeout(obj.foo,100);//0//equivalent to var a = 0;setTimeout(function foo(){console.log(this.a);},100);//0If you want to obtain the a property value in the obj object, you can place the obj.foo function in an anonymous function in the timer for implicit binding.
var a = 0;function foo(){console.log(this.a);};var obj = {a : 2,foo:foo}setTimeout(function(){obj.foo();},100);//2Or you can use the bind method to bind this of the foo() method to obj
var a = 0;function foo(){console.log(this.a);};var obj = {a : 2,foo:foo}setTimeout(obj.foo.bind(obj),100);//2clearTimeout()
The setTimeout function returns an integer value representing the counter number, pass the integer into the clearTimeout function, canceling the corresponding timer
//After 100ms, the console outputs the return value of the setTimeout() method 1var Timer = setTimeout(function(){console.log(Timer);},100);Therefore, this value can be used to cancel the corresponding timer
var Timer = setTimeout(function(){console.log(Timer);},100); clearTimeout(Timer);Or use the return value directly as a parameter
var Timer = setTimeout(function(){console.log(Timer);},100); clearTimeout(1);Generally speaking, the integer value returned by setTimeout is continuous, that is, the integer value returned by the second setTimeout method is 1 larger than the first integer value.
//Console output 1, 2, 3var Timer1 = setTimeout(function(){console.log(Timer1);},100);var Timer2 = setTimeout(function(){console.log(Timer2);},100);var Timer3 = setTimeout(function(){console.log(Timer3);},100);setInterval()
The usage of setInterval is exactly the same as setTimeout. The only difference is that setInterval specifies that a task is executed every once a while, that is, unlimited timed execution
<button id="btn">0</button><script>var timer = setInterval(function(){btn.innerHTML = Number(btn.innerHTML) + 1;},1000);btn.onclick = function(){clearInterval(timer);btn.innerHTML = 0;}</script>[Note] The HTML5 standard stipulates that the shortest time interval of setTimeout is 4 milliseconds; the shortest interval of setInterval is 10 milliseconds, that is, the time interval less than 10 milliseconds will be adjusted to 10 milliseconds
The refresh frequency of most computer monitors is 60HZ, which is roughly equivalent to repainting 60 times per second. Therefore, the optimal loop interval for the smoothest animation effect is 1000ms/60, which is approximately equal to 16.6ms
To save power, the browser expands the time interval to 1000 milliseconds for pages that are not in the current window. In addition, if the laptop is in battery powered, Chrome and IE 9 or above will switch the time interval to the system timer, which is about 16.6 milliseconds
Operation mechanism
Let’s explain the previous part of the question, why does 0 appear in front of 1 in the console result of the code below?
setTimeout(function(){console.log(1);});console.log(0);In fact, setting the second parameter of setTimeout to 0s does not mean executing the function immediately, but just putting the function into the code queue.
In the following example, an event handler is set to a button btn. The event handler sets a timer to call after 250ms. After clicking this button, first add the onclick event handler to the queue. The timer is set after the program is executed. After 250ms, the specified code is added to the queue and wait for execution.
btn.onclick = function(){setTimeout(function(){console.log(1);},250);}If the onclick event handler in the above code has been executed for 300ms, the timer code must be executed at least 300ms after the timer is set. All code in the queue must wait until the JavaScript process is idle, regardless of how they are added to the queue.
As shown in the figure, although the timer code was added at 255ms, it cannot be executed at this time because the onclick event handler is still running. The earliest timer code can be executed is at 300ms, that is, after the onclick event handler is finished
setInterval problem
The problem with using setInterval() is that the timer code may not have been executed before the code is added to the queue again, resulting in the timer code running several times in a row without any pauses between them. The solution to this problem by the javascript engine is to add the timer code to the queue when using setInterval(). This ensures that the minimum time interval for the timer code to be added to the queue is the specified interval
However, this can lead to two problems: 1. Some intervals are skipped; 2. The interval between code execution of multiple timers may be smaller than expected
Suppose that a certain onclick event handler sets a 200ms interval timer using serInterval(). If the event handler takes more than 300ms to complete, and the timer code also takes about the same time, a certain interval will be skipped at the same time.
The first timer in the example is added to the queue at 205ms, but cannot be executed until 300ms have passed. When this timer code is executed, another copy is added to the queue at 405ms. At the next interval, 605ms, the first timer code is still running, and there is already an instance of the timer code in the queue. As a result, the timer code at this point in time will not be added to the queue
Iterate setTimeout
To avoid the problem of setInterval() timer, you can use the chained setTimeout() call
setTimeout(function fn(){setTimeout(fn,interval);},interval);This pattern chain calls setTimeout(), and a new timer is created every time the function is executed. The second setTimeout() calls the currently executed function and sets another timer for it. The advantage of this is that new timer code is not inserted into the queue until the previous timer code is executed, ensuring that there are no missing intervals. Moreover, it ensures that before the next timer code is executed, at least the specified interval must be waited, avoiding continuous operation.
Use setInterval()
<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;position:absolute;left:0;"></div><script>myDiv.onclick = function(){var timer = setInterval(function(){if(parseInt(myDiv.style.left) > 200){clearInterval(timer);return false;}myDiv.style.left = parseInt(myDiv.style.left) + 5 + 'px'; },16); }</script>Use chained setTimeout()
<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;position:absolute;left:0;"></div><script>myDiv.onclick = function(){setTimeout(function fn(){if(parseInt(myDiv.style.left) <= 200){setTimeout(fn,16); }else{return false;}myDiv.style.left = parseInt(myDiv.style.left) + 5 + 'px'; },16); }</script>application
Use timers to adjust the sequence of events
[1] In web development, an event first occurs in the child element and then bubbles up to the parent element, that is, the event callback function of the child element will be triggered earlier than the event callback function of the parent element. If we first let the parent element's event callback function happen first, we need to use setTimeout(f, 0)
Under normal circumstances, click on the div element, first pop up 0, then pop up 1
<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;"></div><script>myDiv.onclick = function(){alert(0);}document.onclick = function(){alert(1);}</script>If you want the onclick event of the document to happen first, that is, click on the div element, 1 will pop up first, and then 0 will pop up. Then make the following settings
<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;"></div><script>myDiv.onclick = function(){setTimeout(function(){alert(0);})}document.onclick = function(){alert(1);}</script>【2】User-defined callback function, usually triggered before the browser's default action. For example, if a user enters text in the input box, the keypress event will be triggered before the browser receives the text. Therefore, the following callback function cannot achieve its goal
<input type="text" id="myInput"><script>myInput.onkeypress = function(event) {this.value = this.value.toUpperCase();}</script>The above code wants to convert the characters to capitalization immediately after the user enters the text. But in fact, it can only convert the previous character to capitalization, because the browser has not received the text at this time, so this.value cannot get the latest input character.
Only by rewriting it with setTimeout can the above code work
<input type="text" id="myInput"><script>myInput.onkeypress = function(event) {setTimeout(function(){myInput.value = myInput.value.toUpperCase();});}</script>The code ends here. The next article will introduce it to you
BOM series: requestAnimationFrame
The third timer application of BOM series (clock, countdown, stopwatch and alarm clock)
The above is the first timer setTimeout and setInterval of the BOM series introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!