0

クロムが呼び出しに対して正確ではないという既知の問題に遭遇しました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>

クロム (28.0.1500.52) を使用して、同じスクリプトを 2 つのタブ (フォーカスのあるタブと非表示のタブ) で開きました。しばらくして、非表示のタイマーに切り替えると、タイマーが数秒遅れています。周期が 1 インチより大きい場合、たとえば 2 または 3 の場合も同様です。

上記のリンクによると、クロムは 1 インチ未満の呼び出しに対してのみ同様の動作を示すはずです。この問題を回避する方法 (jquery ではなく純粋な js) はありますか?

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;
}

Jsフィドル

ところで: を使用setTimeoutすると、いつでもタイマーを停止できるという利点があります ( ... も参照)。

これは、このSO Questionで使用されているタイムアウトの精度をテストするためのページです。

于 2013-07-04T10:32:22.167 に答える