0

我遇到了一个已知问题setInterval(),即 chrome 对呼叫不准确。考虑以下代码(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>

使用铬 (28.0.1500.52),我在 2 个选项卡中打开了相同的脚本,一个具有焦点,一个隐藏。过了一会儿,如果我切换到隐藏的,计时器已经落后了几秒钟。如果周期大于 1'',例如 2 或 3,则同样适用。

根据上面提供的链接,chrome 应该只对小于 1'' 的调用表现出类似的行为。有没有(纯js,不是jquery)解决这个问题?

4

1 回答 1

2

此计时器不会滞后,因为它使用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;
}

提琴手

顺便说一句: usingsetTimeout的优点是可以随时停止计时器(另请参阅...)。

这是一个测试超时准确性的页面,在这个 SO Question中使用。

于 2013-07-04T10:32:22.167 回答