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 相关文章推荐
兼容IE和FF的js脚本代码小结(比较常用)
Dec 06 Javascript
JavaScript实现表格排序方法
Jun 14 Javascript
JavaScript等比例缩放图片控制超出范围的图片
Aug 06 Javascript
如何在指定的地方插入html内容和文本内容
Dec 23 Javascript
JavaScript比较两个对象是否相等的方法
Feb 06 Javascript
实例详解AngularJS实现无限级联动菜单
Jan 15 Javascript
AngularJS 工作原理详解
Aug 18 Javascript
AngularJs  Creating Services详解及示例代码
Sep 02 Javascript
webpack多入口多出口的实现方法
Aug 17 Javascript
js获取对象,数组所有属性键值(key)和对应值(value)的方法示例
Jun 19 Javascript
JavaScript或jQuery 获取option value值方法解析
May 12 jQuery
基于ajax实现上传图片代码示例解析
Dec 03 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过滤危险html代码的函数
2008/07/22 PHP
ThinkPHP标签制作教程
2014/07/10 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
2014/09/27 PHP
php解决DOM乱码的方法示例代码
2016/11/20 PHP
thinkphp5.1 框架钩子和行为用法实例分析
2020/05/25 PHP
jQuery 顺便学习下CSS选择器 奇偶匹配nth-child(even)
2010/05/24 Javascript
JQuery datepicker 使用方法
2011/05/20 Javascript
js获取指定日期前后的日期代码
2013/08/20 Javascript
JS实现固定在右下角可展开收缩DIV层的方法
2015/02/13 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
Jquery+Ajax+PHP+MySQL实现分类列表管理(下)
2015/10/28 Javascript
input 禁止输入特殊字符的四种实现方式
2016/08/24 Javascript
jQuery实现动态文字搜索功能
2017/01/05 Javascript
vue中实现先请求数据再渲染dom分享
2018/03/17 Javascript
基于element-ui封装可搜索的懒加载tree组件的实现
2020/05/22 Javascript
vue实现简易图片左右旋转,上一张,下一张组件案例
2020/07/31 Javascript
[46:02]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第二局
2016/02/28 DOTA
Python中的super用法详解
2015/05/28 Python
从局部变量和全局变量开始全面解析Python中变量的作用域
2016/06/16 Python
tensorflow TFRecords文件的生成和读取的方法
2018/02/06 Python
python实现中文文本分句的例子
2019/07/15 Python
python 计算两个列表的相关系数的实现
2019/08/29 Python
python中round函数如何使用
2020/06/19 Python
python Matplotlib基础--如何添加文本和标注
2021/01/26 Python
Staples美国官方网站:办公用品一站式采购
2016/07/28 全球购物
英国最大的奢侈品零售网络商城:Flannels
2016/09/16 全球购物
给导游的表扬信
2014/01/10 职场文书
电焊工岗位职责
2014/03/06 职场文书
先进个人事迹材料范文
2014/12/30 职场文书
本科毕业论文导师评语
2014/12/31 职场文书
投标承诺函格式
2015/01/21 职场文书
高中教师个人工作总结
2015/02/10 职场文书
如何写通讯稿
2015/07/22 职场文书
22句经典语录:送给优柔寡断和胡思乱想的朋友们
2019/12/13 职场文书
导游词之泉州崇武古城
2019/12/20 职场文书
修改MySQL的数据库引擎为INNODB的方法
2021/05/26 MySQL