Ответы, которые я вижу здесь, работают довольно хорошо, но не совсем строго. Хотя 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();
}
Попробуйте: http://jsfiddle.net/mrwilk/qVuHW
Если ваши часы случайно выровнены очень близко к секундам системных часов, ваш таймер обратного отсчета может показаться «пропущенным» из-за получения событий тайм-аута немного раньше или чуть позже одного секунды. Решение состоит в том, чтобы выровнять ваши события на полсекунды; то есть посередине между ударами секунд системных часов. То, что делают 500 в коде, где 500мс = ½сек.
Единственное, на что стоит обратить внимание, это то, что здесь код отображает часы, а также минуты и секунды; то есть ЧЧ: ММ: СС. Вычислить часы, минуты и секунды из миллисекунд не сложно, но немного неудобно, и проще всего позволить объекту Date сделать эту работу за вас.