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的反射问题
Apr 07 Javascript
Javascript 去除数组的重复元素
May 04 Javascript
JavaScript学习笔记之获取当前目录的实现代码
Dec 14 Javascript
javascript删除数组元素并且数组长度减小的简单实例
Feb 14 Javascript
通过jquery 获取URL参数并进行转码
Aug 18 Javascript
jQuery基础知识小结
Dec 22 Javascript
jQuery实现给页面换肤的方法
May 30 Javascript
解决jQuery uploadify在非IE核心浏览器下无法上传
Aug 05 Javascript
深入探讨Vue.js组件和组件通信
Sep 12 Javascript
Node.js如何实现注册邮箱激活功能 (常见)
Jul 23 Javascript
详解webpack+ES6+Sass搭建多页面应用
Nov 05 Javascript
通过说明与示例了解js五种设计模式
Jun 17 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使用数据库永久连接方式操作MySQL的是与非
2013/06/05 PHP
浅析PHP Socket技术
2013/08/02 PHP
php基础教程
2015/08/26 PHP
Discuz论坛密码与密保加密规则
2016/12/19 PHP
PHP后期静态绑定之self::限制实例分析
2018/12/21 PHP
php让json_encode不自动转义斜杠“/”的方法
2020/04/27 PHP
jQuery插件实现表格隔行换色且感应鼠标高亮行变色
2013/09/22 Javascript
jQuery实现的放大镜效果示例
2016/09/13 Javascript
vue.js指令v-model实现方法
2016/12/05 Javascript
使用Bootstrap + Vue.js实现添加删除数据示例
2017/02/27 Javascript
jQuery Form插件使用详解_动力节点Java学院整理
2017/07/17 jQuery
swiper.js插件实现pc端文本上下滑动功能示例
2018/12/03 Javascript
vux-scroller实现移动端上拉加载功能过程解析
2019/10/08 Javascript
[37:37]DAC2018 4.4 淘汰赛 Optic vs Mineski 第二场
2018/04/05 DOTA
使用Python中的cookielib模拟登录网站
2015/04/09 Python
Python标准库之collections包的使用教程
2017/04/27 Python
django query模块
2019/04/20 Python
Python 保持登录状态进行接口测试的方法示例
2019/08/06 Python
手把手教你pycharm专业版安装破解教程(linux版)
2019/09/26 Python
python 有效的括号的实现代码示例
2019/11/11 Python
Python中zipfile压缩文件模块的基本使用教程
2020/06/14 Python
享誉全球的多元化时尚精品购物平台:Farfetch发发奇(支持中文)
2017/08/08 全球购物
万宝龙英国官网:Montblanc手表、书写工具、皮革和珠宝
2018/10/16 全球购物
美国在线纱线商店:Darn Good Yarn
2019/03/20 全球购物
介绍一下SQL中union,intersect和minus
2012/04/05 面试题
超市采购员岗位职责
2014/02/01 职场文书
食品安全工作实施方案
2014/03/26 职场文书
《社戏》教学反思
2014/04/15 职场文书
八一建军节营销活动方案
2014/08/31 职场文书
乡镇党委书记个人整改措施
2014/09/15 职场文书
小学感恩节活动总结
2015/03/24 职场文书
2015年绩效考核工作总结
2015/05/23 职场文书
教师节老师寄语
2015/05/28 职场文书
校运会班级霸气口号
2015/12/24 职场文书
教你使用TensorFlow2识别验证码
2021/06/11 Python
Javascript使用integrity属性进行安全验证
2021/11/07 Javascript