JavaScript提供定时器(timer)的功能,可以延期执行或重复执行函数或代码段。

window对象提供了三个方法来实现定时器的效果,分别是setTimeout()、setInternal()和requestAnimationFrame()。

定时器是JavaScript动画的核心技术。

setTimeout()

setTimeout()方法用来指定某个函数或代码段/字符串在指定的毫秒数之后执行。它返回一个整数,表示定时器的编号,这个值可以传递给clearTimeout()用来取消这个函数的执行。

var timer = setTimeout(function() {
console.log(timer); // 2.1000ms后,再输出1(1是定时器的编号)
}, 1000);
console.log(0); // 1.先输出0

也可以写成字符串参数的形式,但是这种形式会造成JavaScript引擎的二次解析,降低性能,因此并不推荐使用。

var timer = setTimeout("console.log(timer);", 1000);
console.log(0);

如果省略setTimeout的第二个参数,则该参数默认为0。

var Timer = setTimeout(function() {
console.log(Timer); // 2.过了0ms后,再输出1
});
console.log(0); // 1.先输出0

实际上,除了上面提到的两个参数之外,setTimeout还允许添加更多的参数,它们将被传入到定时器的函数之中。

setTimeout(function(a,b) {
console.log(a + b); // 等待1000ms后,输出2
}, 1000, 1, 1);

要注意的是,IE9及以下的浏览器只支持setTimeout有两个参数,最后的输出结果会是NaN(名副其实的Fuck-IE),这时候可以使用IIFE传参来进行兼容。

setTimeout((function(a, b) {
return function() {
console.log(a + b);
}
})(1, 1), 1000);

或者也可以将函数写在定时器的外面,然后函数在定时器的匿名函数中带参数调用。

function calc(a, b) {
console.log(a + b);
}
setTimeout(function() {
calc(1, 1);
}, 1000);

要注意的是,IE8浏览器不允许向定时器中传递事件对象event,如果要使用事件对象中的某些属性,可以将其保存在变量中传递进去。

div.onclick = function(e) {
e = e || event;
var type = e.type;
setTimeout(function() {
console.log(type); // click
console.log(e.type); // 报错
})
}

cleartimeout()

setTimeout函数返回一个表示计数器编号的整数值,将该整数传入clearTimeout函数就能取消对应的定时器。

var Timer = setTimeout(function() {
console.log(Timer);
}, 100);
clearTimeout(Timer);

或者直接使用返回值作为参数。

var Timer = setTimeout(function() {
console.log(Timer);
}, 100);
clearTimeout(1);

一般来说,setTimeout返回的整数值是连续的,也就是说,第二个setTimeout方法返回的整数值比第一个的整数值大1。

// 控制台输出1、2、3
var Timer1 = setTimeout(function() {
console.log(Timer1);
}, 100);
var Timer2 = setTimeout(function() {
console.log(Timer2);
}, 100);
var Timer3 = setTimeout(function() {
console.log(Timer3);
}, 100);

setInterval()

setInterval()的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行以此,也就是无限次的定时执行。

var count = 0;
var timer = setInterval(function() {
console.log(count++);
}, 1000);

要注意的是,HTML5的标准规定,setTimeout的最短时间间隔是4毫秒;setInterval的最短间隔时间是10毫秒,也就是说,小于10毫秒的时间间隔会被调整到10毫秒。

requestAnimationFrame

计时器一直是javascript动画的核心技术。而编写动画循环的关键是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能让不同的动画效果显得平滑流畅;另一方面,循环间隔还要足够长,这样才能确保浏览器有能力渲染产生的变化。

大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。因此,最平滑动画的最佳循环间隔是1000ms/60,约等于16.6ms。

而setTimeout和setInterval的问题是,它们都不精确。它们的内在运行机制决定了时间间隔参数实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务完成后再执行。

requestAnimationFrame采用系统时间间隔,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。

也就是说,requestAnimationFrame与setTimeout、setInterval不同,不需要设置时间间隔。

requestAnimationFrame的特点

1.requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率。

2.在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量。

3.requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销。

requestAnimationFrame的使用

requestAnimationFrame的用法与settimeout很相似,只是不需要设置时间间隔而已。requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。它返回一个整数,表示定时器的编号,这个值可以传递给cancelAnimationFrame用于取消这个函数的执行。

requestID = requestAnimationFrame(callback); 
// 控制台输出1和0
var timer = requestAnimationFrame(function() {
console.log(0);
});
console.log(timer); //
// 控制台什么都不输出
var timer = requestAnimationFrame(function() {
console.log(0);
});
cancelAnimationFrame(timer);

也可以直接使用返回值进行取消。

var timer = requestAnimationFrame(function() {
console.log(0);
});
cancelAnimationFrame(1);

requestAnimationFrame的兼容

IE9浏览器及以下不支持这个方法,可以使用setTimeout来兼容。

// 简单兼容
if (!window.requestAnimationFrame) {
requestAnimationFrame = function(fn) {
setTimeout(fn, 17);
};
}
// 严格兼容
if(!window.requestAnimationFrame) {
var lastTime = 0;
window.requestAnimationFrame = function(callback) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0,16.7 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
}
} if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}

"最怕你一生碌碌无为,还要安慰自己平凡可贵。"

javascript中的定时器入门的更多相关文章

  1. javascript中的定时器

    本文地址:[http://www.xiabingbao.com/javascript/2015/04/20/javascript-timer/] 在以前的文章[javascript中的定时器]中,简单 ...

  2. [ Javascript ] JavaScript中的定时器(Timer) 是怎样工作的!

    作为入门者来说.了解JavaScript中timer的工作方式是非常重要的.通常它们的表现行为并非那么地直观,而这是由于它们都处在一个单一线程中.让我们先来看一看三个用来创建以及操作timer的函数. ...

  3. 浅谈JavaScript中的定时器

    引言 使用setTimeout()和setInterval()创建的定时器可以实现很多有意思的功能.很多人认为定时器是一个单独的线程(之前我也是),但是JavaScript是运行在单线程环境中的,而定 ...

  4. javascript中的计时器

    javascript中的定时器有两种:一种是一次性定时器,一种是可以持续使用的定时器: 1:一次性定时器setTimeout(a,b):兼容ie的任何版本 该方法接受两个参数,第一个是要执行的代码,第 ...

  5. Unity中的定时器与延时器

    JavaScript中的定时器与延时器,分别是 setInterval.setTimeout,对应的清理函数是:clearInterval.clearTimeout. 而在Unity中,则分别是:In ...

  6. Javascript中定时器的使用方法

    Javascript中定时器的使用方法 1.间隔定时器(每隔一段时间执行一次代码) 格式:setInterval(函数,时间) //时间单位是毫秒,每隔设置的时间执行函数里的内容一遍(一直执行) // ...

  7. javaScript中Number数字类型方法入门

    前言 Number和Math都属于JavaScript中的内置对象,Number数字类型作为基础数据类型,我们在开发过程中会经常用到,包括数字精度的格式化,还有字符串转换成数字等操作. Number数 ...

  8. javaScript中Math内置对象基本方法入门

    概念 Math 是javaScript的内置对象,包含了部分数学常数属性和数学函数方法. Math 不是一个函数对象,用户Number类型进行使用,不支持BigInt. Math 的所有属性与方法都是 ...

  9. 快速入门上手JavaScript中的Promise

    当我还是一个小白的时候,我翻了很多关于Promise介绍的文档,我一直没能理解所谓解决异步操作的痛点是什么意思 直到我翻了谷歌第一页的所有中文文档我才有所顿悟,其实从他的英文字面意思理解最为简单粗暴 ...

随机推荐

  1. ELK 理论小知识

    ELK 是现阶段众多企业单位都在使用的一种日志分析系统,它能够方便的为我们收集你想要的日志并且展示出来 ELK是Elasticsearch.Logstash.Kibana的简称,这三者都是开源软件,通 ...

  2. Python读写Excel表格(简单实用)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:giao窝里giao首先安装两个库:pip install xlrd. ...

  3. 什么是Java优先级队列?

    PriorityQueue是基于无界优先级队列和优先级堆构建的重要Java API之一.本文通过适当的代码示例深入了解了有关此API及其用法的一些复杂信息.另在上篇文章中我们简单地谈了下Java编译器 ...

  4. Day01-基础数据类型/用户交互/流程控制之-if

    1.基础数据类型 什么是数据类型 我们人类可以很容易的分清数字与字符的区别,但是计算机并不能,计算机虽然很强大,但从某种角度上看又很傻,除非你明确的告诉它,1是数字,“汉”是文字,否则它是分不清1和‘ ...

  5. Spring Boot 部署浅析(jar or war)

    对于传统的 ssm 或者 ssh 项目的部署,一般会打包成war包,或者是一个编译好的文件夹,再放到 tomcat 的 webapps 目录下,如果是 war 包,会自动解压出来.而 Spring B ...

  6. 小白的springboot之路(十二)、集成log4j2日志

    0.前言 日志记录对系统来说必不可少,spring boot中常用的日志组件有log4j.logback.log4j2,其中logback是spring boot默认的,已自带:选用log4j2就可以 ...

  7. GitHub 设置和取消代理,加速 git clone

    git 设置代理: git config --global git 取消代理: git config --global --unset http.proxy 针对 github.com 设置代理: g ...

  8. OWASP ModSecurity Core Rule Set (CRS)的基本使用

    Preface 前述文章开源WAF工具ModSecurity,介绍了ModSecurity作为Nginx的动态加载模块的基本安装和使用. 本篇简单介绍ModSecurity CRS规则集的使用. # ...

  9. C++做四则运算的MFC计算器(一)MFC界面创建

    学习最有效的方法就是实战,这两篇文章写了做MFC加减乘除计算器的过程. 第一写前台MFC界面搭建,第二写后台计算原理及代码. MFC编程参考教程:http://www.jizhuomi.com/sch ...

  10. Ajax简单应用之个人简历页面搭建

    1.搭建HTTP静态Web服务器. 代码实现: # 1.导入socket模块 import socket import threading # 创建服务器类 class HttpServerSocke ...