切换页面时加速“setInterval”的速度是多少?

时间:2012-12-20 03:12:04

标签: javascript

这是我的页面,这是一个测试移动元素的演示,但是在某个时候更改页面后,再回到这里,为什么DIV移动得更快?

我的css:

   #box1 {
        width: 900px;
        height: 50px;
        background-color: #000;
        position: relative;
    }

    #box2 {
        width: 50px;
        height: 50px;
        background-color: #a00;
        position: absolute;
    }

我的HTML:

<div id="box1">
    <div id="box2"></div>
</div>

我的Js:

var box2 = document.getElementById("box2");
    var remove = setInterval(function () {
        box2.style.left = "0px";
        var move = setInterval(function () {
            var newLeft = Math.min(parseInt(box2.style.left) + 5, 850) + "px";
            box2.style.left = newLeft;
            if (newLeft == "850px") clearInterval(move)
        }, 20);
    }, 5000)

3 个答案:

答案 0 :(得分:6)

setInterval的费率无法信任。当选项卡没有聚焦时,浏览器可能不会触发它,并且可能会比需要更频繁地触发它。

行为在WindowTimers interface的当前HTML5草案中是标准化的(这并不意味着它是这样实现的)。你会在那里找到说明:

  

此API不保证计时器将按计划运行。由于CPU负载,其他任务等原因导致延迟。

,甚至更明确:

  

9)(可选)等待用户代理定义的另一段时间。

     
    

注意:这旨在允许用户代理根据需要填充超时,以优化设备的电源使用。例如,一些处理器具有低功耗模式,其中定时器的粒度减小;在这样的平台上,用户代理可以降低定时器的速度以适应此计划,而不是要求处理器使用更准确的模式及其相关的更高功耗。

  

您可能还想查看WindowAnimationTiming draft

如果您在动画/时钟/等中使用setInterval / setTimeout,请始终使用Date objects(例如通过Date.now())测量实际经过的时间。

答案 1 :(得分:3)

如果窗口未聚焦,某些浏览器无需触发超时/间隔事件。当窗口重新获得焦点时,它会立即触发所有窗口。这是一个性能决定(如果用户甚至不注意,为什么每毫秒都会触发一个事件?),据我所知,没有办法改变这种行为。

答案 2 :(得分:1)

Mozilla Firefox和Google Chrome都会限制标签处于非活动状态时的间隔时间(来源:http://pivotallabs.com/users/mrushakoff/blog/articles/2035-chrome-and-firefox-throttle-settimeout-setinterval-in-inactive-tabshttps://stackoverflow.com/a/6032591/1756941

所以,正如this answer建议的那样,捕捉日期并根据勾号检查它,以验证它是否正常工作,否则补偿缺失的时间..

JS:

var tick = 20;
var newLeft=0;

var box2 = document.getElementById("box2");
var remove = setInterval(function() {
    box2.style.left = "0px";

 var now, before = new Date();
    var move = setInterval(function() {
        now = new Date();
        var elapsedTime = (now.getTime() - before.getTime());
        if (elapsedTime > tick) {
            console.log((Math.floor(elapsedTime / tick) * 5));
            newLeft = Math.min(parseInt(box2.style.left) + (Math.floor(elapsedTime / tick) * 5), 850) + "px";
        }
        else {
            newLeft = Math.min(parseInt(box2.style.left) + 5, 850) + "px";
        }
        box2.style.left = newLeft;
        before = new Date();
        if (newLeft == "850px"){clearInterval(move);}
    }, tick);

}, 5000);
​

JSFiddle:http://jsfiddle.net/3jY8h/1/