在动画方面,我们被告知 setInterval
是个坏主意。例如,循环将不顾其他任何正在进行的事情而运行,而不是像 requestAnimationFrame
那样礼貌地让步。此外,一些浏览器可能会对 setInterval 循环进行“追赶”,其中一个不活动的选项卡可能一直在排队迭代,然后在再次变为活动状态时非常快地运行所有这些迭代以追赶。
如果你想使用 setInterval
,但又想要 requestAnimationFrame
的性能礼貌,互联网上有一些可用的选项!
var requestInterval = function (fn, delay) {
var requestAnimFrame = (function () {
return window.requestAnimationFrame || function (callback, element) {
window.setTimeout(callback, 1000 / 60);
};
})(),
start = new Date().getTime(),
handle = {};
function loop() {
handle.value = requestAnimFrame(loop);
var current = new Date().getTime(),
delta = current - start;
if (delta >= delay) {
fn.call();
start = new Date().getTime();
}
}
handle.value = requestAnimFrame(loop);
return handle;
};
查看评论 以了解各种变体,例如清除间隔、设置和清除超时。
这是 Joe Lambert 版本的一个变体
window.requestInterval = function(fn, delay) {
if( !window.requestAnimationFrame &&
!window.webkitRequestAnimationFrame &&
!(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support
!window.oRequestAnimationFrame &&
!window.msRequestAnimationFrame)
return window.setInterval(fn, delay);
var start = new Date().getTime(),
handle = new Object();
function loop() {
var current = new Date().getTime(),
delta = current - start;
if(delta >= delay) {
fn.call();
start = new Date().getTime();
}
handle.value = requestAnimFrame(loop);
};
handle.value = requestAnimFrame(loop);
return handle;
}
window.clearRequestInterval = function(handle) {
window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) :
window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) :
window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */
window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) :
window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) :
window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) :
clearInterval(handle);
};
这在一定程度上更加冗长,因为它处理了供应商前缀。你很可能不需要供应商前缀。查看 requestAnimationFrame 的浏览器支持。如果你需要支持 IE 9 或 Android 4.2-4.3,你根本无法使用它。供应商前缀仅对相当旧版本的 Safari 和 Firefox 有帮助。
还有另一个来自 StackExchange 的方法
window.rInterval=function(callback,delay) {
var dateNow=Date.now,
requestAnimation=window.requestAnimationFrame,
start=dateNow(),
stop,
intervalFunc=function() {
dateNow()-start<delay||(start+=delay, callback());
stop||requestAnimation(intervalFunc)
}
requestAnimation(intervalFunc);
return {
clear: function(){ stop=1 }
}
}
感谢您提供此信息!我一直在使用
setInterval
很长一段时间了。