2

这是我的页面,这是一个测试移动元素的演示,但是在您更改页面后,回到这里,为什么 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)
4

3 回答 3

6

的速度setInterval是不可信的。当标签不集中时,浏览器可能不会发射它,并且可能会比所需的更频繁地启动它。

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

此 API 不保证计时器将完全按计划运行。由于 CPU 负载、其他任务等导致的延迟是可以预料的。

而且,更明确:

9) 可选地,等待用户代理定义的时间长度。

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

您可能还想看看WindowAnimationTiming草稿

如果您确实在动画/时钟/等中使用setInterval/ ,请始终使用对象(例如 via )测量实际经过的时间。setTimeoutDateDate.now()

于 2012-12-20T03:22:20.467 回答
3

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

于 2012-12-20T03:16:38.727 回答
1

Mozilla Firefox 和 Google Chrome 都会在选项卡处于非活动状态时限制时间间隔的滴答速度(来源: http: //pivotallabs.com/users/mrushakoff/blog/articles/2035-chrome-and-firefox-throttle-settimeout- setinterval-in-inactive-tabs , https://stackoverflow.com/a/6032591/1756941 )

因此,正如这个答案所建议的那样,捕获日期并根据刻度检查它,以验证它是否正常工作,否则补偿丢失的时间..

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/

于 2012-12-20T03:40:57.777 回答