注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

梦幻雪冰

技在手,能在身,思在脑,从容过生活——陈能堡

 
 
 

日志

 
 

【转载】requestAnimationFrame 与常见计时器的区别(setTimerout,setInterval)  

2015-02-11 20:38:09|  分类: JavaScript |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
以前前端实现动画效果,常用的方法无非计时器或者CSS3的动画效果,计时器分为setTimerout和setInterval,CSS3例如animation,transition等等。
但在实际开发过程中计时器的弊端显而易见,我们要时常提醒自己清计时器,避免内存泄露等很多问题,同时若一个页面同时多个计时器在执行时,页面效果将变得非常不友好,而且不是所有需要计时器效果都能用CSS3去做处理,这在开发移动端时问题将被放大,另外CSS3的也是移动端常用的一种手段,但其实也有很多问题存在,例如使用了CSS3的样式后,小米手机fixed定位就会出问题,只要页面存在了CSS3属性,那么fixed的z-index值就时常会失效,从而出现闪屏的状态,解决方法是给这个fixed的元素添加一个无效的动画效果,例如:

@-webkit-keyframes myfirst {

 0% {

-webkit-transform : rotate(0);

}

 100% {

-webkit-transform : rotate(0);

}

}

这样虽然能很好的解决小米z-index失效的问题,但增加了不必要的代码,也是不怎么好的,所以为了实现动画效果采用哪种方式都有自己的弊端,今天介绍的时另一种性能更好的javascript动画实现方式——requestAnimationFrame。
requestAnimationFrame,是一个专门为实现高性能的动画效果而开发的API,他相对于计时器和CSS3效果而言,优势在于他高效的工作的同时能节省CPU,GPU和内存。假如有个动画效果:
计时器:

var time1 = setInterval(move1)
function move1(){
console.log("正在执行函数1!");
}

通过测试,在我缩小网页上了个厕所的时间内,浏览器都在一直打印“正在执行函数1!”,而我们切换网页去浏览器其他网页时,这段计时器的函数则不再执行,这点还是挺友好的。
CSS3:

<style>
.wrap {
width: 200px;
height: 200px;
margin: 0 auto;
background: #fcf;
-webkit-animation: myfirst 10s linear;
}
@-webkit-keyframes myfirst {
0% {
width: 200px;
}
100% {
width: 1200px;
}
}
</style>
<body>
<div class="wrap"></div>
</body>

经测试发现,不管我们是缩小网页还是切换网页10s,这段CSS3代码都将执行完毕。这在无形当中增加了用户电脑的CPU和内存,不是很友好。同时,CSS3的兼容性太差,而且CSS3只能支持例如带px的属性,这个局限性太明显了。
requestAnimationFrame:

function move2(){
console.log("正在执行函数2!");
requestAnimationFrame(move2)
}
var timer2 = requestAnimationFrame(move2)

测试结果是最好的,无论我们是缩小网页还是切换网页,requestAnimationFrame将不再执行,只有等到我们再次切换或者放大这个网页时他才会继续执行下去,他是根据浏览器的刷新时间进行回调的,故我们要在执行函数中再次添加回调函数,这样才能达到浏览器所能实现动画的最佳效果。
目前支持requestAnimationFrame的浏览器都必须添加浏览器内核,参考CSS3用法,兼容性方面,IE10+和其他主流浏览器都支持,移动端IOS6+和IE mobile 10,都将支持该API,但android原生浏览器不支持,相信不久的将来也能支持。
requestAnimationFrame还有很多功能,这里只是稍微介绍了下他的优势所在。
下面是一个写好的兼容:
(function() {
var lastTime = 0;
var vendors = ['webkit', 'moz'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
window[vendors[x] + 'CancelRequestAnimationFrame'];
}

if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
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);
};
}
}());

  评论这张
 
阅读(11)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017