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 相关文章推荐
如何在Web页面上直接打开、编辑、创建Office文档
Mar 12 Javascript
JavaScript 中的事件教程
Apr 05 Javascript
js字符编码函数区别分析
Jun 05 Javascript
js select常用操作控制代码
Mar 16 Javascript
html+javascript实现可拖动可提交的弹出层对话框效果
Aug 05 Javascript
js制作带有遮罩弹出层实现登录注册表单特效代码分享
Sep 05 Javascript
浅谈JS原型对象和原型链
Mar 02 Javascript
详解使用angular-cli发布i18n多国语言Angular应用
May 20 Javascript
Angular异步变同步处理方法
Aug 13 Javascript
jQuery与原生JavaScript选择HTML元素集合用法对比分析
Nov 26 jQuery
js函数柯里化的方法和作用实例分析
Apr 11 Javascript
Vue+Flask实现图片传输功能
Apr 01 Vue.js
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中提问频率最高的11个面试题和答案
2014/09/02 PHP
PHP实现递归无限级分类
2015/10/22 PHP
PHP中时间加减函数strtotime用法分析
2017/04/26 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
jquery不会自动回收xmlHttpRequest对象 导致了内存溢出
2012/06/18 Javascript
NodeJS与Mysql的交互示例代码
2013/08/18 NodeJs
对于Form表单reset方法的新认识
2014/03/05 Javascript
JavaScript实现按照指定长度为数字前面补零输出的方法
2015/03/19 Javascript
JavaScript实现自动变换表格边框颜色
2015/05/08 Javascript
精通JavaScript的this关键字
2020/05/28 Javascript
Js与Jq获取浏览器和对象值的方法
2016/03/18 Javascript
利用JQuery阻止事件冒泡
2016/12/01 Javascript
javascript ES6中箭头函数注意细节小结
2017/02/17 Javascript
js实现带简单弹性运动的导航条
2017/02/22 Javascript
利用vue组件自定义v-model实现一个Tab组件方法示例
2017/12/06 Javascript
vue实现固定位置显示功能
2019/05/30 Javascript
vue draggable resizable 实现可拖拽缩放的组件功能
2019/07/15 Javascript
Vue 禁用浏览器的前进后退操作
2020/09/04 Javascript
解决Antd Table表头加Icon和气泡提示的坑
2020/11/17 Javascript
[05:31]干嘛呢兄弟!DOTA2 TI9语音轮盘部分出处
2019/05/14 DOTA
[32:56]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第二场 12.11
2020/12/16 DOTA
python利用递归方法实现求集合的幂集
2020/09/07 Python
python+opencv实现车道线检测
2021/02/19 Python
python爬虫scrapy基本使用超详细教程
2021/02/20 Python
HTML+CSS3+JS 实现的下拉菜单
2020/11/25 HTML / CSS
VSCode 自定义html5模板的实现
2019/12/05 HTML / CSS
Cole Haan官方网站:美国时尚潮流品牌
2017/12/06 全球购物
英国最专业的健身器材供应商之一:Best Gym Equipment
2017/12/22 全球购物
哥伦比亚加拿大官网:Columbia Sportswear Canada
2020/09/07 全球购物
关于责任的演讲稿
2014/05/20 职场文书
英语教师求职信
2014/06/16 职场文书
吧主申请感言怎么写
2015/08/03 职场文书
MySQL kill不掉线程的原因
2021/05/07 MySQL
详解redis分布式锁的这些坑
2021/05/19 Redis
SQL Server的存储过程与触发器以及系统函数和自定义函数
2022/04/10 SQL Server
python游戏开发Pygame框架
2022/04/22 Python