Использую вот такой таймер с автокоррекцией, костылями сделал из него обратный таймер (вывод в консоль идет в обратном порядке)
function toFixed(num, fixed) {
return (Math.floor(num * Math.pow(10, fixed)) / Math.pow(10, fixed)).toFixed(fixed);
}
function timerback(time_f) {
var timeout;
var speed = 50;
var finish = (time_f * 1000) / 50;
var counter = 0;
var start = new Date().getTime();
function instance() {
var real = (counter * speed);
var ideal = (new Date().getTime() - start);
counter++;
var diff = (ideal - real);
console.log(toFixed(time_f - toFixed(ideal / 1000.0, 2),2));
if (counter - 1 != finish) {
timeout = setTimeout(function() {
instance();
}, Math.max((speed - diff),0));
} else {
clearTimeout(timeout);
console.log('TIMER FINISH');
}
};
timeout = setTimeout(function() {
instance();
}, speed);
}
timerback(5);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Вызов этой функции происходит вот так timerback(5) 5 - секунд будет ждать таймер. Функция вызывается по суте бесконечно с периодом в 10-15 секунд (такая концепция проекта)
Но если вкладка в браузере не активна, то происходит необъяснимые вещи, то таймер останавливается то считает больше чем надо то меньше.
Вот эта библиотека ничем не помогает https://github.com/turuslan/HackTimer
Как сделать чтобы таймер работал одинаково хорошо вне зависимости от активности вкладки в браузере ?
Из библиотек использую
jquery-3.2.1.min.js
jquery.easing.1.3.js
socket.io.js
accounting.min.js
tinysort.min.js
materialize.min.js
jquery.cookie-1.4.1.min.js
bootstrap.min.js
Таймеры в JS работают крайне нестабильно. Я бы рекомендовал Вам запоминать начальное время, а потом вызвать setInterval с небольшим дискретом. И в ней проверять прошло ли с момента старта достаточно времени
С учетом уточнения
Пользователь должен видеть обратный отсчет 20-ти секунд включая сотые доли секунды например 19.29 (19 секунд | 290 миллисекунд)
var startTime = new Date();
setInterval(function() {
var curTime = new Date();
var delta = curTime.getTime() - startTime.getTime();
if (delta > 20000) {
console.log('20 seconds expired');
startTime = new Date();
} else
document.getElementById('time').innerText = (20 - delta / 1000).toFixed(2);
}, 50);
<div id="time"></div>
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости