0

私はこのようなカウントダウンを持っています:

var countdown = {
    startInterval: function() {
        var count = 600
        var countorig = 600;
        var currentId = setInterval(function() {
            var min = (count - (count % 60)) / 60;
            var sec = count % 60;
            if (sec < 10) {
                $('#timer').html(min + ':0' + sec);
            } else {
                $('#timer').html(min + ':' + sec);
            }
            $('#time').val(countorig - count);
            if (count == 0) {
                $('#form').submit();
            }--count;
        }, 1000);
        countdown.intervalId = currentId;
    }
};

できます。しかし、ページをロードすると、カウントダウンが始まりますが、時計のように「丸い」わけではありません。

JSFiddle .

4

4 に答える 4

1

setInterval正確ではありません。代わりに sを使用Dateして正確な時間を取得し、1 秒未満の間隔を選択して、よりスムーズなクロックを取得する必要があります。これがデモです!

var countdown = {
    startInterval: function() {
        var count = 600;
        var start = new Date(); // The current date!

        var currentId = setInterval(function() {
            var difference = Math.max(0, count - (new Date() - start) / 1000 | 0);
            var min = difference / 60 | 0;
            var sec = difference % 60;

            $('#timer').text(min + ':' + (sec < 10 ? '0' : '') + sec);
            $('#time').val(difference);

            if(count === 0) {
                $('#form').submit();
            }
        }, 200);

        countdown.intervalId = currentId;
    }
};
于 2012-09-29T14:40:54.717 に答える
1

タイマーが正確であると仮定することは決して良い考えではありません。代わりに、デルタ タイミングを使用します。

var startTime = new Date().getTime();
setInterval(function() {
    var elapsed = new Date().getTime()-startTime;
    console.log("Been running for "+Math.floor(elapsed/1000)+" seconds");
},25);
于 2012-09-29T14:41:24.677 に答える
0

を使用してDate.now()、これはカウントダウン関数の簡単な例です(xミリ秒です)

function countdown(x){
    var o = {future: Date.now()+x, last:-1, i:null}; // object so we can pass by-ref if req.

    o.i = setInterval( function() { // use o.i so we can clear interval
        var remain = o.future - Date.now(),
            secs = Math.floor( remain / 1000 ),
            mins = 0;

        if( remain < 0 ){ // finished, do whatever
            return clearInterval(o.i); // then clear & exit
        }

        if( secs === o.last ) return; // skip this iteration if it's not been a second
        o.last = secs; // else update last time

        // do whatever you want for this new second
        if( secs > 59 ) mins = Math.floor( secs / 60 ), secs = secs % 60;
        console.log(
            (mins < 10 ? '0'+mins : mins) + ':' +
            (secs < 10 ? '0'+secs : secs) + ' remain.'
        );
    }, 100);
}

IEで使用されないことがわかっている場合は、間隔内のコールバック関数への引数として、またへの最後の引数として追加することを検討しくださいosetIntervalしたがって、最初の引数としてコールバックに渡されます)。これは、クロージャーが独立していることを意味します=>コールバックどこでも定義できます。

于 2012-09-29T17:52:01.837 に答える
0

これは、setInterval が高精度タイマーであることを意図していないためです。ドットで 1000 ミリ秒ごとにヒットするわけではありません。どちらの方向にも 20 ~ 30 ミリ秒程度の変動があり、クロックがオフになる可能性があります。

于 2012-09-29T14:40:38.257 に答える