我在这里看到的答案效果很好,但并不完全严格。尽管 setInterval() 看起来是正确的函数,但随着时间的推移,它会出现轻微的“漂移”。此外,如果其他一些 JavaScript 函数需要一秒或更长时间才能执行,那么您的倒计时时钟可能会停止并显示错误的时间。
尽管这些情况不太可能发生,但提高精度实际上并不困难。您想要的是一个能够将时钟从不准确的情况中拉回来的计时器。您需要根据系统时钟计算时间,而不是根据时间间隔的频率来计算,为此,您必须放弃 setInterval(),转而使用一系列 setTimeout() 调用。下面的代码展示了如何操作。
function countdown( elementName, minutes, seconds )
{
var element, endTime, hours, mins, msLeft, time;
function twoDigits( n )
{
return (n <= 9 ? "0" + n : n);
}
function updateTimer()
{
msLeft = endTime - (+new Date);
if ( msLeft < 1000 ) {
element.innerHTML = "countdown's over!";
} else {
time = new Date( msLeft );
hours = time.getUTCHours();
mins = time.getUTCMinutes();
element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) +
':' + twoDigits( time.getUTCSeconds() );
setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
}
}
element = document.getElementById( elementName );
endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
updateTimer();
}
Try it: http://jsfiddle.net/mrwilk/qVuHW http://jsfiddle.net/mrwilk/qVuHW
如果您的时钟偶然与系统时钟的秒数非常接近,则您的倒计时器可能会因为在一秒间隔之前或之后接收到超时事件而出现“错过节拍”。解决方案是在半秒内调整您的事件;也就是说,系统时钟的秒拍之间的中间位置。这就是代码中 500 的作用,其中 500 毫秒 = ½ 秒。
唯一值得注意的是,这里的代码显示小时以及分钟和秒;即,HH:MM:SS。从毫秒计算小时、分钟和秒并不困难,但有点尴尬,最简单的方法是让 Date 对象为您完成这项工作。