Имеется такая страница. Часы на ней должны в начале каждого часа отбивать столько раз, сколько сейчас часов. В 9 утра отбить 9 раз, в 15:00 — три раза и т.д.
Вроде всё работает, но есть странная проблема: иногда они отбивают на один час больше, чем надо. Из сегодняшних наблюдений:
12:00 — всё ок
13:00 — всё ок
14:00 — 3 удара в колокол вместо положенных двух
15:00 — 4 удара
16:00 — всё ок. Но при вызове функции из консоли в 16:04 отбил 5 раз.
19:00 — всё ок. Спустя несколько минут вызываю функцию из консоли - отбивает 8 раз.
Проблема наблюдается в Firefox — как десктоптном, так и на Android. В Opera и Chromium (опять же: и на ПК, и на смартфоне) всё в порядке.
Вот функция, вызываемая в начале нового часа. Её же я вызывал через консоль браузера.
function newHour() {
let now = new Date();
// Который час?
full_hours = now.getHours();
// Потребен 12-часовой формат. Аще час больше 12 - надо из оного 12 вычесть. Например, 16-12==4
if (full_hours > 12) {
full_hours -= 12;
}
// Аще средонощие, отбить двана́десять
if (full_hours == 0) {
full_hours = 12;
}
// Аще ныне 1 час, то благовестник отбивает дважды.
// Сего ради костыль: аще full_hours == 1, умножать их на 2834 милисекунд не благословляется!
if (full_hours == 1) {
playback(b1);
}
else {
// Первый удар благовестника будет не сразу по запуску функции, но через 2834 мсек
// Посему один раз отбиваем ДО запуска функции, а затем бьём остальные (сколько там останется)
playback(b1);
let timerId = setInterval(() => { playback(b1); }, 2834);
console.log("Hours: " + full_hours);
/* Один "лишний" удар уже был в начале, до setInterval'а, посему теперь надо отбить на 1 меньше.
Но сие не касается FIREFOX'а. Ему почему-то надо оставить full_hours, как есть.
Поэтому проверяем браузер и по итогам оставляем full_hours без изменений (вычитаем 0) (Firefox)
или вычитаем 1 (все остальные)
*/
let crutch = 1;
if (navigator.userAgent.includes("Firefox")) {
console.log("Тревога: FIREFOX DETECTED! Костыль активирован!");
crutch = 0;
console.log("The crutch is " + crutch + " now");
}
setTimeout(() => { clearInterval(timerId); }, (full_hours - crutch) * 2834); // из еличества часов вычитаем crutch
}
}
Имеются ли на ЛОРе тайновидцы, халдеи и гадатели, способные изъяснить происходящее?
И вдогонку вопрос. Можно ли бой курантов организовать с помощью цикла for? Как-то типа
for (i=1; i<full_hours; i++) {
функция_проигрывания_одного_удара_в_колокол;
пожождать_пару_секунд;
}
У меня указанная схема не сработала.