Предложение: Улучшение работы таймера (точность и защита от дублирования)
Хочу предложить доработку и исправление существующего таймера.
Суть проблемы старой реализации:
Вызов самой функции остался преджний. У вас может возникнуть ошибка Uncaught SyntaxError: Identifier 'timerShowTime' has already been declared. Это означает что вы подключаете файл time.js дважди на одной странице
Хочу предложить доработку и исправление существующего таймера.
Суть проблемы старой реализации:
- Таймер использует setTimeout(..., 1000) и каждый раз уменьшает значение на 1 секунду.
- Однако при переходе на другую вкладку или снижении активности браузера (например, на телефоне), вызовы setTimeout могут замедляться.
- Из-за этого таймер начинает отставать от реального времени.
- Также отсутствует защита от повторного запуска: при многократных вызовах showTime(...) может запускаться несколько таймеров параллельно, что приводит к лишним перерисовкам и багам.
JavaScript:
let timerShowTime;
function ShowTime(fname, totalSeconds, type) {
clearTimeout(timerShowTime);
const element = document.getElementById(fname);
if (!element) return;
const startTime = Date.now();
const endTime = startTime + totalSeconds * 1000;
function update() {
clearTimeout(timerShowTime);
const now = Date.now();
let lefttime = Math.floor((endTime - now) / 1000);
if (lefttime <= 0) {
element.innerText = '';
top.frames['main'].location.reload();
return;
}
const sec = lefttime % 60;
const min = Math.floor(lefttime / 60) % 60;
const hour = Math.floor((lefttime / 3600) % 24);
const day = Math.floor(lefttime / 86400);
const formatTime = (value) => (value < 10 ? `0${value}` : value);
let timeString = '';
if (type === 1) {
timeString = `${min} мин. ${formatTime(sec)} сек.`;
} else if (type === 2) {
if (day > 0) {
timeString = `${day} д. ${hour} ч. ${formatTime(min)} мин. ${formatTime(sec)} сек.`;
} else if (hour > 0) {
timeString = `${hour} ч. ${formatTime(min)} мин. ${formatTime(sec)} сек.`;
} else if (min > 0) {
timeString = `${min} мин. ${formatTime(sec)} сек.`;
} else {
timeString = `${sec} сек.`;
}
} else {
if (day > 0) {
timeString = `${day} д. ${hour} ч. ${formatTime(min)} мин. ${formatTime(sec)} сек.`;
} else {
timeString = `${hour} ч. ${formatTime(min)} мин. ${formatTime(sec)} сек.`;
}
}
element.innerText = timeString;
timerShowTime = setTimeout(update, 1000);
}
update();
}