这是我的页面,这是一个测试移动元素的演示,但是在某个时候更改页面后,再回到这里,为什么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)
答案 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-tabs,https://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/