window.requestAnimationFrame() 方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。
注意:若您想要在下次重绘时产生另一个动画画面,您的回调例程必须调用 requestAnimationFrame()。
回调函数会被传入一个参数,DOMHighResTimeStamp,指示当前被 requestAnimationFrame() 排序的回调函数被触发的时间。即使每个回调函数的工作量的计算都花了时间,单个帧中的多个回调也都将被传入相同的时间戳。该时间戳是一个十进制数,单位毫秒,最小精度为1ms(1000μs)。
语法:
window.requestAnimationFrame(callback);
参数:callback
一个指定函数的参数,该函数在下次重新绘制动画时调用。这个回调函数只有一个传参,DOMHighResTimeStamp,指示requestAnimationFrame() 开始触发回调函数的当前时间(performance.now() 返回的时间)。
返回值:一个 long 整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。
requestAnimationFrame()的特点:
- requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率
- 在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量
- requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销(举个例子比如:页面最小化了,或者被Tab切换了。页面是不会重绘的,自然,requestAnimationFrame也不会调用(没通知啊)。页面绘制全部停止,资源高效利用。)
兼容性:
PC端
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
Basic support | 10 webkit24 [3] | 4.0 moz [1][4] 23 [2] | 10.0 | (Yes) -o15.0 | 6.0 webkit6.1 |
return value | 23 | 11.0 (11.0) | 10.0 | 15.0 | 6.1 |
移动端:
Feature | Android | Android Webview | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile | Chrome for Android |
Basic support | 4.3 webkit4.4 | 4.3 webkit4.4 | 11.0 (11.0) moz23 | 10.0 | 15.0 | 6.1 webkit7.1 | 18 webkit25 [3] |
| 4.4 | 4.4 | 11.0 (11.0) moz | 10.0 | 15.0 | 6.1 webkit7.1 | |
window.cancelAnimationFrame
取消一个先前通过调用window.requestAnimationFrame()方法添加到计划中的动画帧请求.
参数:
- 先前调用window.requestAnimationFrame()方法时返回的ID.
注意:这是一个实验中的功能,此功能某些浏览器尚在开发中,请在不同浏览器中适合使用的前缀。
在 Chrome 中正确取消回调的调用目前是 window.cancelAnimationFrame()。
兼容性不是特别的理想,所以,下面进行了一个封装,解决兼容性问题:
(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'] || // name has changed in Webkit
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);
};
}
}());