长久以来,小弟在做js动画的时候都是使用setTimeout和setInterval,这两个是js里的经典方法了,听过把函数放入执行队列,可以循环我们要的函数
但是这两个方法也有很大的问题,最明显的一点就是不能保证回调函数按时执行(丢失帧),导致画面效果不流畅(话说chrome这方面倒是优化的很不错,时间挺准的),现在有一个新的方法,requestAnimationFrame,这个方法的使用类似setTimeout
requestId = window.requestAFrame(render);
这样就会在下一帧的时候执行render方法,而且你可能注意到了,这个方法没有设置回调时间,因为该方法的回调时间是由浏览器自由调配的,该页面如果是在“活动状态”(你正在看这个页面)的时候,帧数可能达到60帧,如果是在后台的话,可能不会执行(具体取决于浏览器实现,现在还不是的w3c标准)。
或许你和我一样,对于使用requestAnimationFrame不添加回调时间觉得很难理解和不习惯,不过想想css3的动画效果就释然了,我们也只提出我们需要的效果,具体动画调用时间也是浏览器自己设定,这也是requestAnimationFrame的最初灵感来源
requestAnimationFrame 方法(在万维网联合会 (W3C) 的针对基于脚本的动画的计时控制规范中定义)可以解决丢失帧的问题,因为它使应用能够在浏览器需要更新页面显示时(而且仅在这种情况下)获得通知。 因此,应用可与浏览器的绘制时间间隔保持完全一致,并且仅使用适量的资源。从 setTimeout 切换到 requestAnimationFrame 非常容易,因为它们都规划单个回调。要实现持续的动画,请在调用动画函数后再次调用 requestAnimationFrame。——(引用自http://msdn.microsoft.com/zh-cn/library/ie/hh920765(v=vs.85).aspx)
另外一点,这个方法现在还不算标准,虽然浏览器开始支持,但是参数还有些不一样,而兼容写法为:
if ( !window.requestAnimationFrame ) { window.requestAnimationFrame = ( function() { return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) { window.setTimeout( callback, 1000 / 60 ); }; } )(); }
从最后返回的setTimeOut方法中,我们可以看得出,需要的参数是callback,element(ie和firefox不支持),而帧数是60帧(最佳效果的时候)。