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 相关文章推荐
js获取url参数代码实例分享(JS操作URL)
Dec 13 Javascript
javascript实现tab切换的两个实例
Nov 05 Javascript
js省市县三级联动效果实例
Apr 15 Javascript
Angular2使用jQuery的方法教程
May 28 jQuery
Angular客户端请求Rest服务跨域问题的解决方法
Sep 19 Javascript
Angular中点击li标签实现更改颜色的核心代码
Dec 08 Javascript
vue.js element-ui tree树形控件改iview的方法
Mar 29 Javascript
详解如何解决vue开发请求数据跨域的问题(基于浏览器的配置解决)
Nov 12 Javascript
如何解决.vue文件url引用文件的问题
Jan 18 Javascript
vue项目中定义全局变量、函数的几种方法
Nov 08 Javascript
ant-design表单处理和常用方法及自定义验证操作
Oct 27 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
Oct 28 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
PHP 面向对象详解
2012/09/13 PHP
iOS10推送通知开发教程
2016/09/19 PHP
分享PHP-pcntl 实现多进程代码
2016/09/30 PHP
PHP实现腾讯短网址生成api接口实例
2020/12/08 PHP
分页栏的web标准实现
2011/11/01 Javascript
打豆豆小游戏 用javascript编写的[打豆豆]小游戏
2013/01/08 Javascript
jquery 简单应用示例总结
2013/08/09 Javascript
使用纯javascript实现放大镜效果
2015/03/18 Javascript
js实现圆盘记速表
2015/08/03 Javascript
基于JavaScript实现移动端点击图片查看大图点击大图隐藏
2015/11/04 Javascript
基于JavaScript实现Json数据根据某个字段进行排序
2015/11/24 Javascript
js简单实现调整网页字体大小的方法
2016/07/23 Javascript
浅谈jQuery效果函数
2016/09/16 Javascript
在javascript中,null>=0 为真,null==0却为假,null的值详解
2017/02/22 Javascript
JavaScript和JQuery获取DIV值的方法示例
2017/03/07 Javascript
微信小程序 地图map实例详解
2017/06/07 Javascript
使用Vuex实现一个笔记应用的方法
2018/03/13 Javascript
vue 利用路由守卫判断是否登录的方法
2018/09/29 Javascript
服务端预渲染之Nuxt(使用篇)
2019/04/08 Javascript
vue实现全匹配搜索列表内容
2019/09/26 Javascript
微信小游戏中three.js离屏画布的示例代码
2020/10/12 Javascript
[49:21]TNC vs VG 2019DOTA2国际邀请赛淘汰赛 胜者组赛BO3 第三场 8.20.mp4
2019/08/22 DOTA
python按照多个字符对字符串进行分割的方法
2015/03/17 Python
解决python写入mysql中datetime类型遇到的问题
2018/06/21 Python
从列表或字典创建Pandas的DataFrame对象的方法
2019/07/06 Python
python tkinter组件摆放方式详解
2019/09/16 Python
django创建超级用户过程解析
2019/09/18 Python
python生成任意频率正弦波方式
2020/02/25 Python
Python基于字典实现switch case函数调用
2020/07/22 Python
一款利用html5和css3实现的3D立方体旋转效果教程
2016/04/26 HTML / CSS
CSS3教程(4):网页边框和网页文字阴影
2009/04/02 HTML / CSS
英国奢侈品概念店:Base Blu
2019/05/16 全球购物
假日旅行社实习自我鉴定
2013/09/24 职场文书
微电影大赛策划方案
2014/06/05 职场文书
乱世佳人观后感
2015/06/08 职场文书
Redis实现短信验证码登录的示例代码
2022/06/14 Redis