BOM系列第二篇之定时器requestAnimationFrame


Posted in Javascript onAugust 17, 2016

引入

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

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

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

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

特点

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

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

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

使用

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

requestID = requestAnimationFrame(callback); 
//控制台输出1和0
var timer = requestAnimationFrame(function(){
console.log(0);
}); 
console.log(timer);//1 
cancelAnimationFrame方法用于取消定时器
//控制台什么都不输出
var timer = requestAnimationFrame(function(){
console.log(0);
}); 
cancelAnimationFrame(timer);

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

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

兼容

IE9-浏览器不支持该方法,可以使用setTimeout来兼容

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);
};
}

应用

现在分别使用setInterval、setTimeout和requestAnimationFrame这三个方法制作一个简单的进制度效果

【1】setInterval

<div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
<button id="btn">run</button>
<script>
var timer;
btn.onclick = function(){
clearInterval(timer);
myDiv.style.width = '0';
timer = setInterval(function(){
if(parseInt(myDiv.style.width) < 500){
myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
myDiv.innerHTML = parseInt(myDiv.style.width)/5 + '%'; 
}else{
clearInterval(timer);
} 
},16);
}
</script>

BOM系列第二篇之定时器requestAnimationFrame

【2】setTimeout

<div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
<button id="btn">run</button>
<script>
var timer;
btn.onclick = function(){
clearTimeout(timer);
myDiv.style.width = '0';
timer = setTimeout(function fn(){
if(parseInt(myDiv.style.width) < 500){
myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
myDiv.innerHTML = parseInt(myDiv.style.width)/5 + '%';
timer = setTimeout(fn,16);
}else{
clearTimeout(timer);
} 
},16);
}
</script>

BOM系列第二篇之定时器requestAnimationFrame

【3】requestAnimationFrame

<div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
<button id="btn">run</button>
<script>
var timer;
btn.onclick = function(){
myDiv.style.width = '0';
cancelAnimationFrame(timer);
timer = requestAnimationFrame(function fn(){
if(parseInt(myDiv.style.width) < 500){
myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
myDiv.innerHTML = parseInt(myDiv.style.width)/5 + '%';
timer = requestAnimationFrame(fn);
}else{
cancelAnimationFrame(timer);
} 
});
}
</script>

BOM系列第二篇之定时器requestAnimationFrame

好了,代码到此介绍,下面给大家介绍BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)

以上所述是小编给大家介绍的BOM系列第二篇之定时器requestAnimationFrame ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
Apr 21 Javascript
符合标准的js表单提交的代码
Sep 13 Javascript
IE和FireFox(FF)中js和css的不同
Apr 13 Javascript
jquery实现的元素的left增加N像素 鼠标移开会慢慢的移动到原来的位置
Mar 21 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
Aug 24 Javascript
JS特殊函数(Function()构造函数、函数直接量)区别介绍
May 19 Javascript
IE下window.onresize 多次调用与死循环bug处理方法介绍
Nov 12 Javascript
JS获取单击按钮单元格所在行的信息
Jun 17 Javascript
浅谈JavaScript 中有关时间对象的方法
Aug 15 Javascript
Bootstrap导航条学习使用(二)
Feb 08 Javascript
解决Angular.js中使用Swiper插件不能滑动的问题
Feb 26 Javascript
基于javascript处理nginx请求过程详解
Jul 07 Javascript
AngularJS 视图详解及示例代码
Aug 17 #Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
Aug 17 #Javascript
AngularJS Ajax详解及示例代码
Aug 17 #Javascript
AngularJS包括详解及示例代码
Aug 17 #Javascript
详细分析Javascript中创建对象的四种方式
Aug 17 #Javascript
AngularJS表单详解及示例代码
Aug 17 #Javascript
AngularJS模块详解及示例代码
Aug 17 #Javascript
You might like
PHP5在Apache下的两种模式的安装
2006/09/05 PHP
对盗链说再见...
2006/10/09 PHP
php 文件上传后缀名与文件类型对照表(几乎涵盖所有文件)
2010/05/16 PHP
PHP读取汉字的点阵数据
2015/06/22 PHP
javascript对talbe进行动态添加、删除、验证实现代码
2012/03/29 Javascript
JavaScript包装对象使用介绍
2013/08/29 Javascript
ExtJS4 表格的嵌套 rowExpander应用
2014/05/02 Javascript
JavaScript 获取任一float型小数点后两位的小数
2014/06/30 Javascript
js单独获取一个checkbox看其是否被选中
2014/09/22 Javascript
node.js中的fs.createWriteStream方法使用说明
2014/12/17 Javascript
javascript实现简单的分页特效
2015/08/12 Javascript
bootstrap datetimepicker日期插件使用方法
2017/01/13 Javascript
在vue-cli中组件通信的方法
2017/12/16 Javascript
JQuery实现table中tr上移下移的示例(超简单)
2018/01/08 jQuery
vue主动刷新页面及列表数据删除后的刷新实例
2018/09/16 Javascript
微信小程序缓存支持二次开发封装实现解析
2019/12/16 Javascript
如何实现iframe父子传参通信
2020/02/05 Javascript
基于javascript处理nginx请求过程详解
2020/07/07 Javascript
Node在Controller层进行数据校验的过程详解
2020/08/28 Javascript
[01:07]2015国际邀请赛 中国区预选赛精彩回顾
2015/06/15 DOTA
Python中实现三目运算的方法
2015/06/21 Python
python SocketServer源码深入解读
2019/09/17 Python
瑞典领先的汽车零部件网上零售商:bildelaronline24.se
2017/01/12 全球购物
如何判断一段程序是由C 编译程序还是由C++编译程序编译的
2013/08/04 面试题
服装销售人员求职自我评价
2013/09/26 职场文书
人事档案接收函
2014/01/12 职场文书
青年教师典范事迹材料
2014/01/31 职场文书
2014年公司植树节活动方案
2014/03/04 职场文书
个人委托书怎么写
2014/04/04 职场文书
高二学生评语大全
2014/04/25 职场文书
大学班级文化建设方案
2014/05/06 职场文书
小学生母亲节演讲稿
2014/05/07 职场文书
2014和解协议书范文
2014/09/15 职场文书
2014年卫生保健工作总结
2014/12/08 职场文书
Java比较两个对象中全部属性值是否相等的方法
2021/08/07 Java/Android
一次Mysql update sql不当引起的生产故障记录
2022/04/01 MySQL