javascript中的定时器入门
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中的定时器入门的更多相关文章
- javascript中的定时器
本文地址:[http://www.xiabingbao.com/javascript/2015/04/20/javascript-timer/] 在以前的文章[javascript中的定时器]中,简单 ...
- [ Javascript ] JavaScript中的定时器(Timer) 是怎样工作的!
作为入门者来说.了解JavaScript中timer的工作方式是非常重要的.通常它们的表现行为并非那么地直观,而这是由于它们都处在一个单一线程中.让我们先来看一看三个用来创建以及操作timer的函数. ...
- 浅谈JavaScript中的定时器
引言 使用setTimeout()和setInterval()创建的定时器可以实现很多有意思的功能.很多人认为定时器是一个单独的线程(之前我也是),但是JavaScript是运行在单线程环境中的,而定 ...
- javascript中的计时器
javascript中的定时器有两种:一种是一次性定时器,一种是可以持续使用的定时器: 1:一次性定时器setTimeout(a,b):兼容ie的任何版本 该方法接受两个参数,第一个是要执行的代码,第 ...
- Unity中的定时器与延时器
JavaScript中的定时器与延时器,分别是 setInterval.setTimeout,对应的清理函数是:clearInterval.clearTimeout. 而在Unity中,则分别是:In ...
- Javascript中定时器的使用方法
Javascript中定时器的使用方法 1.间隔定时器(每隔一段时间执行一次代码) 格式:setInterval(函数,时间) //时间单位是毫秒,每隔设置的时间执行函数里的内容一遍(一直执行) // ...
- javaScript中Number数字类型方法入门
前言 Number和Math都属于JavaScript中的内置对象,Number数字类型作为基础数据类型,我们在开发过程中会经常用到,包括数字精度的格式化,还有字符串转换成数字等操作. Number数 ...
- javaScript中Math内置对象基本方法入门
概念 Math 是javaScript的内置对象,包含了部分数学常数属性和数学函数方法. Math 不是一个函数对象,用户Number类型进行使用,不支持BigInt. Math 的所有属性与方法都是 ...
- 快速入门上手JavaScript中的Promise
当我还是一个小白的时候,我翻了很多关于Promise介绍的文档,我一直没能理解所谓解决异步操作的痛点是什么意思 直到我翻了谷歌第一页的所有中文文档我才有所顿悟,其实从他的英文字面意思理解最为简单粗暴 ...
随机推荐
- 【Java】在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
题目描述: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整 ...
- SpringBoot整合axis1.4后,@Autowired注入失败,使用工具类注入
问题描述: 费劲心思搭建好webservices服务端后,没想到客户端调用失败,查看日志文件,发现报空指针异常,debug代码后,发现sql查询的值都是null.通常情况下,我们将Dao注入Servi ...
- C#线程学习笔记八:async & await入门一
一.涉及内容 async & await是C# 5.0引入的,控制台输出所使用的$符号(拼接字符串)是C# 6.0引入的,其功能类似于string.Format()方法. 二.多线程.异步.同 ...
- Wiki语法大全
原文链接:wiki语法大全 编辑一个维客页面十分容易.只要点击页面上方的“编辑本页”或右侧的[编辑]链接即可修改该页,或点击“讨论本页”然后再点击“编辑页面”来讨论该页面.点击后您就会看到一个包含那 ...
- HTML DOM 学习
HTML DOM 学习 By: Mirror王宇阳 E-mail:2821319009@qq.com 博客主页:https://www.cnblogs.com/wangyuyang1016/ DOM ...
- HTTP认知(请求与响应)
web的工作是:浏览器发送请求报文 + 服务端返回响应报文 通俗的说一下web工作的一个流程: 浏览器向服务端发送HTTP请求报文:这条请求报文组成由请求行.请求头.请求体三大部分组成: 1.请求行 ...
- Java面试必看之Integer.parseInt()与Integer.valueOf()
Integer.parseInt()和Integer.valueOf()都是将成为String转换为Int,但是为什么Java会提供两个这样的方法呢,他们如果是同样的操作,岂不是多此一举? 我们来深挖 ...
- webpack 配置babel-loader babel7
babel 7版本配置 在webpack中 默认只能处理部分 ES6的新语法,一些更高级的ES6或ES7的语法,webpack是处理不了的这个时候就需要借助第三方的loader 来帮助webpack ...
- 转pytorch中训练深度神经网络模型的关键知识点
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_42279044/articl ...
- Python高级特性——迭代器
可以直接用for循环的数据类型有: 集合数据类型,如:list.tuple.dict.set.str等: 生成器generator,包括生成器和带yield的generator function. 以 ...