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实现控制内容的向上向下滚动效果
Jun 26 Javascript
高亮显示web页表格行的javascript代码
Nov 19 Javascript
jquery判断浏览器类型的代码
Nov 05 Javascript
JS+CSS设置img在DIV中只显示Img垂直居中的部分
Oct 24 Javascript
web前端设计师们常用的jQuery特效插件汇总
Dec 07 Javascript
jQuery插件实现大图全屏图片相册
Mar 14 Javascript
JS实现从顶部下拉显示的带动画QQ客服特效代码
Oct 24 Javascript
解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
Dec 03 Javascript
Bootstrap select下拉联动(jQuery cxselect)
Jan 04 Javascript
vue 下列表侧滑操作实例代码详解
Jul 24 Javascript
vue仿element实现分页器效果
Sep 13 Javascript
vue项目上传Github预览的实现示例
Nov 06 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微信公众号开发之秒杀
2018/10/20 PHP
CheckBox 如何实现全选?
2006/06/23 Javascript
JSON 数据格式介绍
2012/01/13 Javascript
JS、CSS以及img对DOMContentLoaded事件的影响
2014/08/12 Javascript
jquery实现触发时更新下拉列表内容的方法
2015/12/02 Javascript
Vue.use源码分析
2017/04/22 Javascript
JS中的三个循环小结
2017/06/20 Javascript
webpack实现热更新(实施同步刷新)
2017/07/28 Javascript
Iphone手机、安卓手机浏览器控制默认缩放大小的方法总结(附代码)
2017/08/18 Javascript
node文字生成图片的示例代码
2017/10/26 Javascript
纯js代码生成可搜索选择下拉列表的实例
2018/01/11 Javascript
JavaScript数组基于交换的排序示例【冒泡排序】
2018/07/21 Javascript
JavaScript中BOM对象原理与用法分析
2019/07/09 Javascript
three.js利用gpu选取物体并计算交点位置的方法示例
2019/11/25 Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
2019/12/15 Javascript
[12:51]71泪洒现场!是DOTA2让经典重现
2014/03/24 DOTA
使用Python来开发Markdown脚本扩展的实例分享
2016/03/04 Python
Python文件如何引入?详解引入Python文件步骤
2018/12/10 Python
python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结
2019/07/04 Python
django最快程序开发流程详解
2019/07/19 Python
django框架forms组件用法实例详解
2019/12/10 Python
全面总结使用CSS实现水平垂直居中效果的方法
2016/03/10 HTML / CSS
CSS3 实用技巧:实现黑白图像效果示例代码
2013/07/11 HTML / CSS
HTML5移动端手机网站开发流程
2016/04/25 HTML / CSS
基于HTML5+CSS3实现简单的时钟效果
2017/09/11 HTML / CSS
Genny意大利官网:意大利高级时装品牌
2020/04/15 全球购物
医药营销专业个人自荐信
2013/09/29 职场文书
岗位职责的含义
2013/11/17 职场文书
安全生产先进个人材料
2014/02/06 职场文书
销售团队获奖感言
2014/08/14 职场文书
党支部审查意见
2015/06/02 职场文书
php 解析非标准json、非规范json
2021/04/01 PHP
使用Pytorch实现two-head(多输出)模型的操作
2021/05/28 Python
Python selenium的这三种等待方式一定要会!
2021/06/10 Python
Smart 2 车辆代号 HC11 全新谍照曝光
2022/04/21 数码科技
MySQL事务的隔离级别详情
2022/07/15 MySQL