私たちのアプリケーションでは、堅牢なカウントダウン タイマーが必要です。タイマーがゼロになると、ユーザーを次のページに移動させます。
JavaScript でカウントダウン タイマーを作成することについて、ここには多くの質問があります。私はそれらの多くを整理し、多くのコード サンプルを調べ、多くのプラグインを試しましたが、この 1 つのテスト ケースではすべて失敗しました。 (時間を稼ぐ、時間を失う、または単にフリーズする)。その理由は、それらのほとんどが、最初の開始時刻を保存してから、(setTimeout または setInterval のいずれかを介して) 一定の間隔で現在の時刻を取得し、それと開始時刻の差分を取るというロジックに基づいているためです。システム時刻を調整すると、「現在の」時刻は、開始時刻の 1 時間または数日前、または数時間または数日後になる場合があります。
そこで、これらのシステム変更シナリオを処理するために、次のコードを考え出しました。私が行う主なことは、目盛り間隔を近似値として使用するために、開始時と現在の「差分」が負であるかどうか (または、自動夏時間調整を処理するために約 1 時間以上かどうか) を確認することです。また、開始時刻を各ティックの現在の時刻にリセットして、経過時間が最初の開始時刻と現在の時刻の差分だけでなく、差分間の時間の合計になるようにします。このアプローチに欠陥がある人はいますか?
var timeLeft = 60000, // time left in ms, 1 minute for this example
startTime,
totalElapsedTime = 0,
TICK_INTERVAL = 500; // the setTimeout interval
var timerTick = function () {
var now = new Date(),
elapsedTime = now.getTime() - startTime.getTime();
// if the elapsed time was positive and less than approximately an hour, then add the elapsed time to the total
// otherwise, add the TICK_INTERVAL, which we know is the theoretical minimum between timerTick() calls
totalElapsedTime = (elapsedTime > 0 && elapsedTime < 3590000) ? totalElapsedTime + elapsedTime : totalElapsedTime + TICK_INTERVAL;
// reset start time
startTime = now;
// there is time left, so set up another tick
if (totalElapsedTime < timeLeft) {
// update the html that is displaying remaining time
setTimeout(timerTick, TICK_INTERVAL);
}
else {
// time ran out, so do whatever you do when it runs out
}
}
// start the timer
startTime = new Date();
setTimeout(timerTick, TICK_INTERVAL);