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 相关文章推荐
jQuery实现Twitter的自动文字补齐特效
Nov 28 Javascript
BootStrap table表格插件自适应固定表头(超好用)
Aug 24 Javascript
详解JavaScript中的属性和特性
Dec 08 Javascript
微信小程序(六):列表上拉加载下拉刷新示例
Jan 13 Javascript
vue实现百度搜索下拉提示功能实例
Jun 14 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
Jan 23 Javascript
JS实现面向对象继承的5种方式分析
Jul 21 Javascript
React styled-components设置组件属性的方法
Aug 07 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
Apr 17 Javascript
vue路由传参页面刷新参数丢失问题解决方案
Oct 08 Javascript
JavaScript 监听组合按键思路及代码实现
Jul 28 Javascript
Vue-cli打包后部署到子目录下的路径问题说明
Sep 02 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查询搜索引擎排名位置的代码
2010/01/05 PHP
PHP代码维护,重构变困难的4种原因分析
2016/01/25 PHP
Yii2语言国际化自动配置详解
2018/08/22 PHP
浅析php如何实现爬取数据原理
2018/09/27 PHP
Thinkphp5.0框架视图view的循环标签用法示例
2019/10/12 PHP
学习YUI.Ext第五日--做拖放Darg&amp;Drop
2007/03/10 Javascript
一些常用且实用的原生JavaScript函数
2010/09/08 Javascript
zTree插件之多选下拉菜单实例代码
2013/11/06 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
jfinal与bootstrap的登录跳转实战演习
2015/09/22 Javascript
JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
2015/12/02 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
JavaScript设计模式经典之命令模式
2016/02/24 Javascript
bootstrap布局中input输入框右侧图标点击功能
2016/05/16 Javascript
jquery中的常见问题及快速解决方法小结
2016/06/14 Javascript
详解vue2.0脚手架的webpack 配置文件分析
2017/05/27 Javascript
解决vue-cli创建项目的loader问题
2018/03/13 Javascript
解决bootstrap中下拉菜单点击后不关闭的问题
2018/08/10 Javascript
微信小程序实现的五星评价功能示例
2019/04/25 Javascript
微信小程序wx.navigateTo中events属性实现页面间通信传值,数据同步
2019/07/13 Javascript
p5.js绘制创意自画像
2019/11/04 Javascript
Python的Flask框架及Nginx实现静态文件访问限制功能
2016/06/27 Python
Python操作配置文件ini的三种方法讲解
2019/02/22 Python
Python tkinter布局与按钮间距设置方式
2020/03/04 Python
Python numpy矩阵处理运算工具用法汇总
2020/07/13 Python
python中uuid模块实例浅析
2020/12/29 Python
如何用Python和JS实现的Web SSH工具
2021/02/23 Python
使用纯HTML5编写一款网页上的时钟的代码分享
2015/11/16 HTML / CSS
html2canvas截图空白问题的解决
2020/03/24 HTML / CSS
阿玛尼美妆英国官网:Giorgio Armani Beauty英国
2019/03/28 全球购物
本科生求职简历的自我评价
2013/10/21 职场文书
专科应届生求职信
2013/11/24 职场文书
幼儿园亲子活动总结
2014/04/26 职场文书
投标保密承诺书
2014/05/19 职场文书
承诺书格式范文
2014/06/03 职场文书
CSS元素定位之通过元素的标签或者元素的id、class属性定位详解
2022/09/23 HTML / CSS