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
Sep 24 Javascript
利用webqq协议使用python登录qq发消息源码参考
Apr 08 Javascript
JS正则验证邮箱的格式详细介绍
Nov 19 Javascript
JS实现的用来对比两个用指定分隔符分割的字符串是否相同
Sep 19 Javascript
javascript创建对象、对象继承的实用方式详解
Mar 08 Javascript
jQuery禁用快捷键例如禁用F5刷新 禁用右键菜单等的简单实现
Aug 31 Javascript
基于javascript实现按圆形排列DIV元素(三)
Dec 02 Javascript
Vuex模块化实现待办事项的状态管理
Mar 15 Javascript
原生javascript实现分页效果
Apr 21 Javascript
JS自定义滚动条效果简单实现代码
Oct 27 Javascript
微信小程序实现红包雨功能
Jul 11 Javascript
vue2.0 可折叠列表 v-for循环展示的实例
Sep 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
德生S2000收音机更换“钕铁硼”全频扬声器
2021/03/02 无线电
php 三元运算符实例详细介绍
2016/12/15 PHP
JavaScript页面刷新与弹出窗口问题的解决方法
2010/03/02 Javascript
js读写cookie实现一个底部广告浮层效果的两种方法
2013/12/29 Javascript
JS实现控制表格内指定单元格内容对齐的方法
2015/03/30 Javascript
js操作DOM--添加、删除节点的简单实例
2016/07/08 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
angularjs使用directive实现分页组件的示例
2017/02/07 Javascript
nodejs 子进程正确的打开方式
2017/07/03 NodeJs
浅谈Vue 自动化部署打包上线
2020/06/14 Javascript
vue+echarts实现动态折线图的方法与注意
2020/09/01 Javascript
Node.js利用Express实现用户注册登陆功能(推荐)
2020/10/26 Javascript
[15:56]Heroes18_暗影萨满(完美)
2014/10/31 DOTA
python类继承与子类实例初始化用法分析
2015/04/17 Python
python返回昨天日期的方法
2015/05/13 Python
python itchat实现微信好友头像拼接图的示例代码
2017/08/14 Python
Python 异常处理的实例详解
2017/09/11 Python
Python线程创建和终止实例代码
2018/01/20 Python
Python 3.x 安装opencv+opencv_contrib的操作方法
2018/04/02 Python
Numpy数组的保存与读取方法
2018/04/04 Python
详解Python logging调用Logger.info方法的处理过程
2019/02/12 Python
python实现知乎高颜值图片爬取
2019/08/12 Python
Python数据可视化 pyecharts实现各种统计图表过程详解
2019/08/15 Python
python实现猜拳游戏
2020/03/04 Python
在Windows上安装和配置 Jupyter Lab 作为桌面级应用程序教程
2020/04/22 Python
英国图书音像网站:Hive.co.uk(图书、电子书、DVD、蓝光、音乐CD等)
2017/10/16 全球购物
Swanson中国官网:美国斯旺森健康产品公司
2021/03/01 全球购物
请说出以下代码输出什么
2013/08/30 面试题
开业庆典答谢词
2014/01/18 职场文书
环境保护与污染治理求职信
2014/07/16 职场文书
学习十八届四中全会依法治国心得体会
2014/11/03 职场文书
2015公司年度工作总结
2015/05/14 职场文书
2015年团支部年度工作总结
2015/05/27 职场文书
人生哲理妙语30条:淡写流年,笑过人生
2019/09/04 职场文书
python3 hdf5文件 遍历代码
2021/05/19 Python
Python实现提取PDF简历信息并存入Excel
2022/04/02 Python