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 09 Javascript
用js一次改变多个input的readonly属性值的方法
Jun 11 Javascript
jquery实现带缩略图的可定制高度画廊效果(5种)
Aug 28 Javascript
详解jQuery中的deferred对象的使用(一)
May 27 Javascript
KnockoutJS 3.X API 第四章之数据控制流with绑定
Oct 10 Javascript
微信小程序 石头剪刀布实例代码
Jan 04 Javascript
javascript防篡改对象实例详解
Apr 10 Javascript
详解Immutable及 React 中实践
Mar 01 Javascript
使用taro开发微信小程序遇到的坑总结
Apr 08 Javascript
微信小程序系列之自定义顶部导航功能
May 21 Javascript
Vue父组件如何获取子组件中的变量
Jul 24 Javascript
jQuery实现可以计算进制转换的计算器
Oct 19 jQuery
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
不用数据库的多用户文件自由上传投票系统(3)
2006/10/09 PHP
解析Win7 XAMPP apache无法启动的问题
2013/06/26 PHP
php的XML文件解释类应用实例
2014/09/22 PHP
php检查日期函数checkdate用法实例
2015/03/19 PHP
php字符集转换
2017/01/23 PHP
基于laravel-admin 后台 列表标签背景的使用方法
2019/10/03 PHP
PHP 图片合成、仿微信群头像的方法示例
2019/10/25 PHP
JavaScript入门教程(9) Document文档对象
2009/01/31 Javascript
js 文件引入实现代码
2010/04/23 Javascript
手把手教你自己写一个js表单验证框架的方法
2010/09/14 Javascript
div层的移动及性能优化
2010/11/16 Javascript
深入理解JavaScript是如何实现继承的
2013/12/12 Javascript
js判断子窗体是否关闭的方法
2015/08/11 Javascript
基于Bootstrap的Metronic框架实现页面链接收藏夹功能
2016/08/29 Javascript
利用jquery实现验证输入的是否是数字、小数,包含保留几位小数
2016/12/07 Javascript
jquery mobile实现可折叠的导航按钮
2017/03/11 Javascript
jQuery返回定位插件详解
2017/05/15 jQuery
解析Json字符串的三种方法日常常用
2018/05/02 Javascript
微信小程序点击生成朋友圈分享图(遇到的坑)
2020/06/17 Javascript
Django中反向生成models.py的实例讲解
2018/05/30 Python
python str字符串转uuid实例
2020/03/03 Python
PageFactory设计模式基于python实现
2020/04/14 Python
keras 权重保存和权重载入方式
2020/05/21 Python
pycharm 关掉syntax检查操作
2020/06/09 Python
使用Python爬虫爬取小红书完完整整的全过程
2021/01/19 Python
详解如何修改jupyter notebook的默认目录和默认浏览器
2021/01/24 Python
基于HTML5 的人脸识别活体认证的实现方法
2016/06/22 HTML / CSS
捷克建筑材料网上商店:DEK.cz
2021/03/06 全球购物
教师应聘自荐信范文
2014/03/14 职场文书
付款委托书范本
2014/04/04 职场文书
说明书范文
2014/05/07 职场文书
世界遗产导游词
2015/02/13 职场文书
聘任书格式及范文
2015/09/21 职场文书
小学生组织委员竞选稿
2015/11/21 职场文书
MySQL分库分表详情
2021/09/25 MySQL
Python中itertools库的四个函数介绍
2022/04/06 Python