我遇到了一个已知的问题,chrome对setInterval()
调用不精确。考虑以下代码(jsfiddle:http://jsfiddle.net/periklis/j6AU8/),显示一个简单的计时器:
<span id = "time_left"></span>
<script>
seconds = 0;
minutes = 10;
hours = 0;
setInterval(function () {
if (seconds >= 1) {seconds--;}
else {
if (seconds == 0 ) {seconds = 59;}
if (minutes >= 1) {minutes--;}
else {
if (minutes == 0) {minutes = 59;}
if (hours >= 1) {hours--;}
else {hours = 0;}
}
}
min = minutes.toString();
sec = seconds.toString()
if (min.length == 1) {min = "0" + min;}
if (sec.length == 1) {sec = "0" + sec;}
document.getElementById("time_left").innerHTML = hours + ":" + min + ":" + sec;
}, 1000);
</script>
使用chromium(28.0.1500.52),我在两个选项卡中打开了相同的脚本,一个具有焦点,另一个隐藏。过了一段时间,如果我切换到隐藏的,计时器就会滞后几秒钟。如果周期大于1'',比如说2或3,也是如此。
根据上面提供的链接,chrome应该只对小于1''的调用表现出类似的行为。有没有(纯js,而不是jquery)可以解决这个问题?
此计时器不会滞后,因为它使用Date
对象检查"实时"时间。
var endTime = new Date;
endTime.setMinutes(then.getMinutes()+10);
refresh();
function refresh(){
var diff = Math.abs((endTime-new Date().getTime())/1000);
document.getElementById("time_left").innerHTML =
zeroPad(Math.floor(diff/3600)) +
":" + zeroPad(Math.floor(diff/60))+
":" + zeroPad(Math.floor((diff%60)));
if (new Date < endTime){
setTimeout(refresh,1000);
}
}
// zeroPad method:
function zeroPad(nr,base,chr){
var len = (String(base||10).length - String(nr).length)+1;
return len > 0? new Array(len).join(chr||'0')+nr : nr;
}
JsFiddle
BTW:使用setTimeout
的优点是可以随时停止计时器(另请参阅…)
这是一个测试超时准确性的页面,在这个SO问题中使用。