[翻译]增强版setTimeout() / setInterval()

时间:2022-12-20 15:06:48

更新(2011/07/09)

Firefox 5实现 mozRequestAnimationFrame 但没有 mozCancelRequestAnimationFrame,为了确保下面的函数正常运行,代码进行了调整,强制Firefox使用setTimeout/setInterval,直到mozCancelRequestAnimationFrame可用为止。


更新(2011/06/04)

修正了函数,so that they can be cancelled with drop in replace functions for clearTimeout() & clearInterval()。

================================================

我之前翻译了一篇文章介绍requestAnimationFrame(),这个函数的目的是为了取代setTimeout()或setInterval(),因为它有更好的性能。


这个函数能实现60fps的帧频,这确实很赞,但是你也许并不希望调用callback的频率是60fps,特别是当你不是在做动画时,而setTimeout()和setInterval()可以实现任意的帧频。

setTimeout(function(){ alert("hello world") }, 1000)

这段代码会在1000毫秒后调用函数。


所以,我们既想获得requestAnimationFrame()的优点,同时也需要setTimeout()和setInterval()的灵活易用。

接下来隆重推出我的作品:requestTimeout()和requestInterval()。

1. requestTimeout(fn, delay)

window.requestTimeout = function(fn, delay) {
    if( !window.requestAnimationFrame       && 
        !window.webkitRequestAnimationFrame && 
        !window.mozRequestAnimationFrame    && 
        !window.oRequestAnimationFrame      && 
        !window.msRequestAnimationFrame)
            return window.setTimeout(fn, delay);

    var start = new Date().getTime(),
        handle = new Object();

    function loop(){
        var current = new Date().getTime(),
        delta = current - start;

        delta >= delay ? fn.call() : handle.value = requestAnimFrame(loop);
    };

    handle.value = requestAnimFrame(loop);
    return handle;
};

window.clearRequestTimeout = function(handle) {
    window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) :
    window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value)   :
    window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) :
    window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) :
    window.msCancelRequestAnimationFrame ? msCancelRequestAnimationFrame(handle.value) :
    clearTimeout(handle);
};


2. requestInterval(fn, delay)

window.requestInterval = function(fn, delay) {
    if( !window.requestAnimationFrame       && 
        !window.webkitRequestAnimationFrame && 
        !window.mozRequestAnimationFrame    && 
        !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.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value)   :
    window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) :
    window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) :
    window.msCancelRequestAnimationFrame ? msCancelRequestAnimationFrame(handle.value) :
    clearInterval(handle);
};


这两个函数都需要 [翻译]使用requestAnimationFrame实现炫目的动画 提到的requestAnimFrame()

原文