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 相关文章推荐
javascript检查日期格式的函数[比较全]
Oct 17 Javascript
页面js遇到乱码问题的解决方法是和无法转码的情况
Apr 30 Javascript
使用AngularJS实现可伸缩的页面切换的方法
Jun 19 Javascript
JavaScript实现自动切换图片代码
Oct 11 Javascript
EasyUI修改DateBox和DateTimeBox的默认日期格式示例
Jan 18 Javascript
Bootstrap Scrollspy源码学习
Mar 02 Javascript
无循环 JavaScript(map、reduce、filter和find)
Apr 08 Javascript
AngularJS之ionic 框架下实现 Localstorage本地存储
Apr 22 Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
Feb 16 Javascript
jQuery实现轮播图及其原理详解
Apr 12 jQuery
vue data恢复初始化数据的实现方法
Oct 31 Javascript
Vue程序化的事件监听器(实例方案详解)
Jan 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
第十四节 命名空间 [14]
2006/10/09 PHP
在windows平台上构建自己的PHP实现方法(仅适用于php5.2)
2013/07/05 PHP
php将session放入memcached的设置方法
2014/02/14 PHP
PHP实现对文本数据库的常用操作方法实例演示
2014/07/04 PHP
php+mysqli实现将数据库中一张表信息打印到表格里的方法
2015/01/28 PHP
php生成验证码,缩略图及水印图的类分享
2016/04/07 PHP
php生成HTML文件的类方法
2019/10/11 PHP
jquery cookie插件代码类
2009/05/26 Javascript
Javascript中的window.event.keyCode使用介绍
2011/04/26 Javascript
Query中click(),bind(),live(),delegate()的区别
2013/11/19 Javascript
js实现完美兼容各大浏览器的人民币大小写相互转换
2015/10/29 Javascript
简单的js表格操作
2016/09/24 Javascript
jQuery插件版本冲突的处理方法分析
2017/01/16 Javascript
基于node.js的fs核心模块读写文件操作(实例讲解)
2017/09/10 Javascript
浅谈vue中使用图片懒加载vue-lazyload插件详细指南
2017/10/23 Javascript
iview form清除校验状态的实现
2019/09/19 Javascript
countup.js实现数字动态叠加效果
2019/10/17 Javascript
微信小程序getLocation 需要在app.json中声明permission字段
2020/03/03 Javascript
解决Vue中的生命周期beforeDestory不触发的问题
2020/07/21 Javascript
python实现用户答题功能
2018/01/17 Python
利用Python实现在同一网络中的本地文件共享方法
2018/06/04 Python
python爬取网页内容转换为PDF文件
2020/07/28 Python
python获取中文字符串长度的方法
2018/11/14 Python
python 执行终端/控制台命令的例子
2019/07/12 Python
使用pandas实现连续数据的离散化处理方式(分箱操作)
2019/11/22 Python
NumPy排序的实现
2020/01/21 Python
Pytorch通过保存为ONNX模型转TensorRT5的实现
2020/05/25 Python
纯CSS3绘制打火机动画火焰效果
2016/07/18 HTML / CSS
Luxplus荷兰:以会员价购买美容产品等,独家优惠
2019/08/30 全球购物
中学生在校期间的自我评价分享
2013/11/13 职场文书
大学活动策划书范文
2014/01/10 职场文书
洗发水广告词
2014/03/13 职场文书
入股协议书
2014/04/14 职场文书
民族学专业职业生涯规划范文:积跬步以至千里
2014/09/11 职场文书
高中生第一学年自我鉴定2015
2014/09/28 职场文书
银行保安拾金不昧表扬稿
2015/05/05 职场文书