setTimeout в неактивной вкладке

284
06 декабря 2017, 23:40

Использую вот такой таймер с автокоррекцией, костылями сделал из него обратный таймер (вывод в консоль идет в обратном порядке)

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
Answer 1

Таймеры в 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>

READ ALSO
Движение элемента в эллипсе

Движение элемента в эллипсе

Всем доброго дняПодскажите пожалуйста, как реализовать данную задачу

194
JQUERY animate не работает несколько раз подряд

JQUERY animate не работает несколько раз подряд

И так, вот код ниже, он крутит тюленюшку по кнопке, делает 2 оборота + случайные 100-300 градусовТак вот если нажать кнопку, подождать завершения...

288
Как управлять элементом на странице при перетаскивании его мышкой [drag&amp;drop]

Как управлять элементом на странице при перетаскивании его мышкой [drag&drop]

Привет всем! Ребята, есть задача создать конструктор украшенийЕсть лента элементов и рабочая область на которой расположен шнурок

186
Удаление дублей в select multiple

Удаление дублей в select multiple

Есть функция которая вызывает следующий код:

238