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介绍的文档,我一直没能理解所谓解决异步操作的痛点是什么意思 直到我翻了谷歌第一页的所有中文文档我才有所顿悟,其实从他的英文字面意思理解最为简单粗暴 ...
随机推荐
- GTC 2019参会整理
NVIDIA GTC 2019在苏州金湖国际会议中心举行,由于同事有其他会议冲突,所以我代替他来参加了此次会议.作为刚接触GPU和机器学习不久的新人来说,感觉进入了一个新世界,深刻体验到技术的革新迭代 ...
- JavaSE-知识点总结
Java名词 变量.运算符.类.接口.枚举.参数.注解.异常.包装类.多线程.集合.IO流.网络编程.反射.Lambda.API 源文件:.java文件,存储Java源代码的文件 字节码文件:.cla ...
- Caffe源码-SGDSolver类
SGDSolver类简介 Solver类用于网络参数的更新,而SGDSolver类实现了优化方法中的随机梯度下降法(stochastic gradient descent),此外还具备缩放.正则化梯度 ...
- Rancher 2.3实现K8S一键式升级!再也不用同步升级Rancher啦!
在Rancher 2.3之前,Rancher的新版本总是随着Kubernetes的新版本一起发布,如果你想要使用最新版本的Kubernetes,那么你需要先升级Rancher才能使用.Rancher ...
- 小程序 wx.request请求
1.wx.request相当于发送ajax请求 微信官方解释 参数 属性 类型 默认值 必填 说明 url string 是 开发者服务器接口地址 data string/object/ArrayBu ...
- Geoserver设置style
1 背景 我们在ArcMap中可以直接通过symbol功能对图层进行定制化配图.但是,如果我们将配好图的shp图层在GeoServer中发布时,会发现图层样式完全丢失了.其实原因很简单,用ArcMap ...
- Sqlite—修改语句(Update)
SQLite 的 UPDATE 语句用于修改表中已有的记录.可以使用带有 WHERE 子句的 UPDATE 查询来更新选定行,否则所有的行都会被更新. 基本语法:UPDATE table_name S ...
- 2019/12/11学习内容摘要(Linux系统用户与用户组管理①)
一,认识/etc/passwd和/etc/shadow 1. /etc/passwd :文件中保存系统中所有的用户和用户的主要信息. 在命令行输入 cat /etc/passwd | head ( ...
- Nuxt+Vuex初体验
小呀嘛小二郎,背着书包上学堂... 今天一个困扰了我一周时间的问题终于被我解决了,值得庆祝 在Nuxt中使用Vuex实现数据存储 首先: 在store目录下新建一个index.js文件 需要有两个组件 ...
- eth-trunk学习笔记
转载自https://blog.csdn.net/qq_38265137/article/details/80404340