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 前的按键判断代码
Mar 19 Javascript
使用jquery实现以post打开新窗口
Mar 19 Javascript
JavaScript函数学习总结以及相关的编程习惯指南
Nov 16 Javascript
Jquery操作Ajax方法小结
Nov 29 Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
May 16 Javascript
angularjs实现简单的购物车功能
Sep 21 Javascript
解决vue脚手架项目打包后路由视图不显示的问题
Sep 20 Javascript
angular 未登录状态拦截路由跳转的方法
Oct 09 Javascript
javascript数组常见操作方法实例总结【连接、添加、删除、去重、排序等】
Jun 13 Javascript
详解使用WebPack搭建React开发环境
Aug 06 Javascript
vue封装swiper代码实例解析
Oct 08 Javascript
JavaScript 事件代理需要注意的地方
Sep 08 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
浅析PKI加密解密 OpenSSL
2013/07/01 PHP
解决laravel资源加载路径设置的问题
2019/10/14 PHP
基于jquery实现后台左侧菜单点击上下滑动显示
2013/04/11 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
实例说明为什么不要行内使用javascript
2014/04/18 Javascript
jQuery将多条数据插入模态框的示例代码
2014/09/25 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
Nodejs获取网络数据并生成Excel表格
2020/03/31 NodeJs
JS组件Bootstrap Table使用实例分享
2016/05/30 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
2016/07/04 Javascript
jquery中用jsonp实现搜索框功能
2016/10/18 Javascript
js时间查询插件使用详解
2017/04/07 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
2018/08/09 jQuery
微信小程序实现留言板功能
2018/11/02 Javascript
Vue 幸运大转盘实现思路详解
2019/05/06 Javascript
详解使用JWT实现单点登录(完全跨域方案)
2019/08/02 Javascript
Javascript执行流程细节原理解析
2020/05/14 Javascript
python基础教程之基本数据类型和变量声明介绍
2014/08/29 Python
Python Queue模块详解
2014/11/30 Python
详解Python的Django框架中的模版相关知识
2015/07/15 Python
Python实现SMTP发送邮件详细教程
2021/03/02 Python
深入理解Python中range和xrange的区别
2017/11/26 Python
python utc datetime转换为时间戳的方法
2019/01/15 Python
通过cmd进入python的实例操作
2019/06/26 Python
Windows平台Python编程必会模块之pywin32介绍
2019/10/01 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
python使用pygame实现笑脸乒乓球弹珠球游戏
2019/11/25 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
使用HTML5捕捉音频与视频信息概述及实例
2018/08/22 HTML / CSS
乌克兰移动电子产品和相关配件的在线商店:iTMag
2020/03/16 全球购物
讲文明懂礼貌演讲稿
2014/09/11 职场文书
小学教研工作总结2015
2015/05/13 职场文书
大学生暑期实践报告
2015/07/13 职场文书
Python与C++中梯度方向直方图的实现
2022/03/17 Python
Redis 操作多个数据库的配置的方法实现
2022/03/23 Redis
vue-cli3.x配置全局的scss的时候报错问题及解决
2022/04/30 Vue.js