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 相关文章推荐
点弹代码 点击页面任何位置都可以弹出页面效果代码
Sep 17 Javascript
两个多选select(multiple左右)添加、删除选项和取值实例
May 12 Javascript
jquery结婚电子请柬特效源码分享
Aug 21 Javascript
jquery实现右侧栏菜单选择操作
Mar 04 Javascript
AngularJS基础 ng-include 指令示例讲解
Aug 01 Javascript
Vue常用指令V-model用法
Mar 08 Javascript
Angular4.0中引入laydate.js日期插件的方法教程
Dec 25 Javascript
详解React 的几种条件渲染以及选择
Oct 23 Javascript
vue如何自动化打包测试环境和正式环境的dist/test文件
Jun 06 Javascript
layui点击按钮页面会自动刷新的解决方案
Oct 25 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
Apr 28 Javascript
Vue如何实现变量表达式选择器
Feb 18 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中实现汉字转区位码应用源码实例解析
2010/06/14 PHP
浅谈PHP与C#的值类型指向区别的详解
2013/05/21 PHP
基于PHP Socket配置以及实例的详细介绍
2013/06/13 PHP
wordpress之js库集合研究介绍
2007/08/17 Javascript
HTA版JSMin(省略修饰语若干)基于javascript语言编写
2009/12/24 Javascript
jQuery 1.4 15个你应该知道的新特性(译)
2010/01/24 Javascript
高性能web开发 如何加载JS,JS应该放在什么位置?
2010/05/14 Javascript
通过JQuery将DIV的滚动条滚动到指定的位置方便自动定位
2014/05/05 Javascript
javascript面向对象特性代码实例
2014/06/12 Javascript
JavaScript实现点击单元格改变背景色的方法
2016/02/12 Javascript
关于JS中的方法是否加括号的问题
2016/07/27 Javascript
Vue.js基础知识小结
2017/01/13 Javascript
jQuery 实现鼠标画框并对框内数据选中的实例代码
2017/08/29 jQuery
javascript帧动画(实例讲解)
2017/09/02 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
vuejs中监听窗口关闭和窗口刷新事件的方法
2018/09/21 Javascript
浅析微信小程序modal弹窗关闭默认会执行cancel问题
2019/10/14 Javascript
Python3.x中自定义比较函数
2015/04/24 Python
python的re正则表达式实例代码
2018/01/24 Python
python 去除txt文本中的空格、数字、特定字母等方法
2018/07/24 Python
pthon贪吃蛇游戏详细代码
2019/01/27 Python
浅谈Python_Openpyxl使用(最全总结)
2019/09/05 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
CSS3中Color的一些特性介绍
2012/05/27 HTML / CSS
兰蔻美国官网:Lancome美国
2017/04/25 全球购物
凯普林包包西班牙官网:Kipling西班牙
2019/04/12 全球购物
墨西哥购物网站:Elektra
2020/01/21 全球购物
为什么在使用动态 SQL 语句时必须为低层数据库对象授予权限
2012/12/13 面试题
马智宇婚礼主持词
2014/03/22 职场文书
小学师德师风演讲稿
2014/09/02 职场文书
先进事迹材料怎么写
2014/12/30 职场文书
小学生2015教师节演讲稿
2015/03/19 职场文书
小学数学新课改心得体会
2016/01/22 职场文书
微信小程序中使用vant框架的具体步骤
2022/02/18 Javascript
最新最全的手机号验证正则表达式
2022/02/24 Javascript
win10音频服务未响应怎么解决?win10音频服务未响应未修复的解决方法
2022/08/14 数码科技