First part of BOM series: timer setTimeout and setInterval, bomsettimeout
SetTimeout ()
The setTimeout () method is used to specify a function or string to be executed after a specified number of milliseconds. It returns an integer indicating the timer number. This value can be passed to clearTimeout () to cancel the execution of this function.
In the following code, the console outputs 0 first. After about ms, that is, 1 s, the setTimeout () method returns 1.
var Timer = setTimeout(function(){console.log(Timer);},1000);console.log(0);
It can also be written as a string parameter, because this form will cause the javascript engine to parse twice, reducing performance, so it is not recommended to use
var Timer = setTimeout('console.log(Timer);',1000);console.log(0);
If the second parameter of setTimeout is omitted, the default value is 0.
In the following code, the console displays 0 and 1, but 0 is in front of it. This question will be explained later.
var Timer = setTimeout(function(){console.log(Timer);});console.log(0);
In fact, apart from the first two parameters, the setTimeout () method also allows you to add more parameters, which will be passed into the functions in the timer.
In the following code, the console outputs 2 after about ms (1 S), while the IE9-browser only allows setTimeout to have two parameters. If more parameters are not supported, NaN is output on the console.
setTimeout(function(a,b){console.log(a+b);},1000,1,1);
You can use IIFE to pass parameters to function parameters that are compatible with the IE 9-browser.
setTimeout((function(a,b){return function(){console.log(a+b);}})(1,1),1000);
Or write the function out of 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
The this mechanism series has detailed four binding rules pointed to by this. Because this in the timer is implicitly lost and prone to errors, we will explain it 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); // 0
If you want to obtain the property value of the obj object, you can place the obj. foo function in the anonymous function of 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);//2
Alternatively, 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);//2
ClearTimeout ()
The setTimeout function returns an integer representing the counter number. The integer is passed into the clearTimeout function to cancel the corresponding timer.
// After 100ms, the console outputs the setTimeout () method's return value 1var Timer = setTimeout (function () {console. log (Timer) ;}, 100 );
So we can use this value to cancel the corresponding timer.
var Timer = setTimeout(function(){console.log(Timer);},100);clearTimeout(Timer);
Or directly use the return value as the parameter.
var Timer = setTimeout(function(){console.log(Timer);},100);clearTimeout(1);
In general, the integer returned by setTimeout is continuous, that is, the integer returned by the second setTimeout method is 1 larger than the first integer.
// The console outputs 1, 2, and 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 that of setTimeout. The difference is that setInterval specifies that a task is executed every time, that is, an unlimited number of scheduled executions.
<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] According to the HTML5 standard, the shortest interval of setTimeout is 4 milliseconds; the shortest interval of setInterval is 10 milliseconds, that is, the interval between less than 10 milliseconds is adjusted to 10 milliseconds.
Most computer monitors refresh at a frequency of 60 HZ, which is about 60 times a second. Therefore, the optimal cycle interval of the smoothest animation effect is 1000 ms/60, which is about 16.6 ms.
To save power, the browser will extend the time interval to 1000 milliseconds for pages not in the current window. In addition, if the laptop is battery, Chrome and IE 9 or later versions will switch the time interval to the system timer, which is about 16.6 milliseconds
Operating Mechanism
The following explains the questions left over from the previous section. Why does 0 appear before 1 in the console result of the following code?
setTimeout(function(){console.log(1);});console.log(0);
In fact, setting the second parameter of setTimeout to 0 s does not mean to execute the function immediately, but simply puts the function into the code queue.
In the following example, an event handler is set for the button btn. The event handler sets a timer called after Ms. Click this button to first add The onclick event handler to the queue. The timer is set only after the program is executed. After ms, the specified code is added to the queue for execution.
btn.onclick = function(){setTimeout(function(){console.log(1);},250);}
If the onclick event handler in the above Code executes 300 ms, the timer code must be executed at least ms after the timer is set. All the code in the queue can be executed only after the JavaScript process is idle, no matter how they are added to the queue
, Although the timer code is added at ms, it cannot be executed because the onclick event handler is still running. The earliest time when the timer code can be executed is at ms, that is, after the onclick event handler ends
SetInterval Problems
The problem with setInterval () is that the timer Code may not be executed until the code is added to the queue again. As a result, the timer code runs continuously for several times without any pause. The javascript Engine solves this problem: when setInterval () is used, the timer code is added to the queue only when there are no other code instances with the timer. This ensures that the minimum interval for the timer code to be added to the queue is the specified interval.
However, this will cause two problems: 1. Some intervals are skipped; 2. The interval between code execution of multiple timers may be smaller than expected
Assume that an onclick event handler uses serInterval () to set a timer with an interval of Ms. If the event processing program takes a little more than ms to complete and the timer Code takes almost the same time, a certain interval may be skipped at the same time.
In this example, the first timer is added to the queue in 20 ms, but can only be executed after Ms. When this timer code is executed, another copy is added to the queue within 40 ms. At the next interval (60 ms), the first timer code is still running, and an instance of the timer code is already in the queue. The result is that the timer code at this time point will not be added to the queue.
Iteration setTimeout
To avoid the setInterval () timer problem, you can use the setTimeout () chain to call
setTimeout(function fn(){setTimeout(fn,interval);},interval);
SetTimeout () is called in this mode. A new timer is created every time a function is executed. The second setTimeout () calls the currently executed function and sets another timer for it. The advantage of doing so is that no new timer code is inserted into the queue before the previous timer code is executed, ensuring that there is no missing interval. In addition, it can ensure that at least the specified interval must be waited before the next timer code is executed to avoid 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 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 a timer to adjust the Event Sequence
[1] In web development, an event first occurs in the child element and then bubbles to the parent element, that is, the Event Callback Function of the child element, which is triggered before the Event Callback Function of the parent element. If the Event Callback Function of the parent element occurs first, setTimeout (f, 0) is used)
Normally, click the div element to bring up 0 first and then 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 to enable the onclick event of the document to occur first, that is, click the div element, first 1 is displayed, and then 0 is displayed. The following settings are performed:
<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 functions are usually triggered before the default action of the browser. For example, if you enter text in the input box, the keypress event is triggered before the browser receives the text. Therefore, the following callback function cannot reach the goal.
<input type="text" id="myInput"><script>myInput.onkeypress = function(event) {this.value = this.value.toUpperCase();}</script>
The code above converts the characters to uppercase immediately after the user enters the text. But in fact, it can only convert the previous character to uppercase, because the browser has not received the text at this time, so this. value cannot get the character that is newly entered
The above code can be used only when setTimeout is used for rewriting.
<input type="text" id="myInput"><script>myInput.onkeypress = function(event) {setTimeout(function(){myInput.value = myInput.value.toUpperCase();});}</script>
The Code ends here. Next I will introduce it to you
The second part of BOM series: timer requestAnimationFrame
Part 3 of BOM series timer applications (clock, countdown, stopwatch, and alarm)
The above section describes the timer setTimeout and setInterval in the first part of the BOM series. I hope to help you. If you have any questions, please leave a message, the editor will reply to you in a timely manner. Thank you very much for your support for the help House website!