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 相关文章推荐
JQuery 实现的页面滚动时浮动窗口控件
Jul 10 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
Dec 30 Javascript
解析JavaScript中instanceof对于不同的构造器或许都返回true
Dec 03 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
Feb 20 Javascript
下雪了 javascript实现雪花飞舞
Aug 02 Javascript
基于JavaScript实现轮播图代码
Jul 14 Javascript
Javascript发送AJAX请求实例代码
Aug 21 Javascript
layui之select的option叠加问题的解决方法
Mar 08 Javascript
使用JavaScript破解web
Sep 28 Javascript
JavaScript实现背景自动切换小案例
Sep 27 Javascript
element-ui 弹窗组件封装的步骤
Jan 22 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
Eclipse的PHP插件PHPEclipse安装和使用
2014/07/20 PHP
typecho插件编写教程(二):写一个新插件
2015/05/28 PHP
PHP内置函数生成随机数实例
2019/01/18 PHP
PHP使用递归按层级查找数据的方法
2019/11/10 PHP
精通JavaScript 纠正 cleanWhitespace函数
2010/03/11 Javascript
关于JS控制代码暂停的实现方法分享
2012/10/11 Javascript
js数组去重的方法汇总
2015/07/29 Javascript
解决js图片加载时出现404的问题
2020/11/30 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
Node.js开启Https的实践详解
2016/10/25 Javascript
JavaScript中setTimeout的那些事儿
2016/11/14 Javascript
Angular.Js的自动化测试详解
2016/12/09 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
2017/10/09 jQuery
微信小程序实现列表页的点赞和取消点赞功能
2018/11/02 Javascript
vue cli 3.x 项目部署到 github pages的方法
2019/04/17 Javascript
微信小程序传值以及获取值方法的详解
2019/04/29 Javascript
微信小程序绑定手机号获取验证码功能
2019/10/22 Javascript
小程序实现投票进度条
2019/11/20 Javascript
Vue中nprogress页面加载进度条的方法实现
2020/11/13 Javascript
Python 命令行参数sys.argv
2008/09/06 Python
Django中的Signal代码详解
2018/02/05 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
python实现textrank关键词提取
2018/06/22 Python
浅析python中numpy包中的argsort函数的使用
2018/08/30 Python
Python读入mnist二进制图像文件并显示实例
2020/04/24 Python
scrapy redis配置文件setting参数详解
2020/11/18 Python
详解canvas drawImage()方法绘制图片不显示的问题
2018/10/08 HTML / CSS
Intimissimi德国网上商店:意大利知名内衣品牌
2018/04/03 全球购物
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
不开辟用于交换数据的临时空间,如何完成字符串的逆序
2012/12/02 面试题
介绍一下Ruby的多线程处理
2013/02/01 面试题
成品库仓管员岗位职责
2014/04/06 职场文书
计算机软件专业求职信
2014/06/10 职场文书
会议开幕词
2015/01/28 职场文书
2016医师资格考试考生诚信考试承诺书
2016/03/25 职场文书
2016年圣诞节义工活动总结
2016/04/01 职场文书