当我们写window.requestAnimationFrame(回调函数)
时,浏览器会在下次重绘前执行回调函数。
我们可以用它来做连贯的逐帧动画。例如:
function render(){
// 一些更新界面的操作
requestAnimationFrame(render);
}
render();
在没有requestAnimationFrame
方法之前,我们只能用setTimeout
或setInterval
来实现类似的效果
function render(){
// 一些更新界面的操作
setTimeout(render, 1000/60);// 一般浏览器是每秒60帧
}
render();
这样写的存在的问题是:如果浏览器不是每秒60帧,会造成掉帧。
还有,在性能方面,大部分在浏览器在标签页/窗口处于的时候非激活状态(如窗口最小化或标签页切换了)时,requestAnimationFrame
是不会被执行的,而setTimeout/setInterval
会。具体如下
requestAnimationFrameIsStop.png
如上图所示, 只有 Firefox和chrome对 setInterval
做了优化:只有时间间隔超过1s,setInterval才会在非激活的标签页/窗口中执行。
browserCompatibility.png
在老的浏览器中,requestAnimationFrame
的方法名是带浏览器前缀的。以下是张鑫旭为在各个浏览器中能统一的调用requestAnimationFrame
做的处理。不支持requestAnimationFrame
的用setTimeout
来代替。
/* requestAnimationFrame.js
* by zhangxinxu 2013-09-30
*/
(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);
};
}
}());
这样,就可以在所有的浏览器(包括IE6)中使用requestAnimationFrame
啦~
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有