定时器
都是不精确的
定时器里的事件属于下一次事件队列,定时器时间再短,也是定时器后面的代码先执行,然后才是定时器里面的代码执行
每一个定时器都对应这一个序号,从1开始排列,用后需要清除定时器
setTimeout()
- 用来指定某个函数或字符串在指定的毫秒数之后执行,只会执行一次
- 第一参数为函数,作为执行体,第二个参数为执行间隔时间(毫秒)
注意:对函数传递参数的时候,可以把实参放在执行间隔时间的后面(不兼容IE9及以下,在IE里面用闭包的形式去写)
clearTimeout()
-
清除定时器,参数为定时器的名称
<script>// 不兼容IE9及以下var timer1 = setTimeout(function(a, b){console.log(a + b); // 3},1000,1,2);document.onclick = function(){clearTimeout(timer1); // 清除计时器1clearTimeout(timer2); // 清除计时器2console.log("停止定时器 " + timer1); // 停止定时器 1 console.log("停止定时器 " + timer2); // 停止定时器 2 }// 兼容IE9及以下的闭包写法var timer2 = setTimeout((function(a, b){return function(){console.log(a + b); // 3}})(1,2),1000); </script>
setInterval()
- setInterval()和setTimeout()一样,但是会无限执行
clearInterval()
-
参数为定时器clearInterval()的名称
<script>var str = "a";var obj = {str : "b",foo : func,}function func(){console.log(this.str);}let timer1 = setInterval(obj.foo,1000); // a 不是b,函数作为参数传递会造成隐式丢失,this指向Windowlet timer2 = setInterval(function(){console.log("b");},1000);document.onclick = function(){console.log("停止定时器");clearInterval(timer1);clearInterval(timer2);}console.log(timer1,timer2); // 1 2 此行代码优先于定时器里的代码执行 </script>
案例
-
5s后跳转百度
<div id="wrap">页面将在<span>5s</span>之后跳转</div> <script>let oSpan = document.getElementsByTagName("span")[0],num = 5;let timer = setInterval(function(){num --;oSpan.innerHTML = `${num}s`;if(num===0){window.open("http://www.baidu.com","_self");clearInterval(timer);}},1000); </script>
requestAnimationFrame()
- 现在做动画使用的帧函数(不兼容IE10及以下)
注意:它除了在外部执行函数体,也要在执行函数体里面自己执行 -
cancelAnimationFrame()清除定时器
<script>// 这是requestAnimationFrame的兼容写法window.requestAnimationFrame = (function(){return window.requestAnimationFrame ||window.webkitRequsetAnimationFrame ||window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||window.msRequestAnimationFrame ||function(callback){window.setTimeout(callback,1000/60);};})();let a = 0;function func(){a++;console.log(a);requestAnimationFrame(func);}requestAnimationFrame(func); </script>