Приостановка setInterval, когда страница/браузер не в фокусе

У меня есть простое слайд-шоу, которое я сделал на главной странице клиента, используя setInterval для временного вращения.

Чтобы предотвратить зависание браузеров setInterval, когда страница не находится в фокусе (просматривается другая вкладка или другая программа), я использую:

function onBlur() {
            clearInterval(play);
        };

        function onFocus() {

            mySlideRotateFunction();

        };

        if (/*@[email protected]*/false) { 
            document.onfocusin = onFocus;
            document.onfocusout = onBlur;
        } else {
            window.onfocus = onFocus;
            window.onblur = onBlur;
        }

Где mySlideRotateFunction устанавливает setInterval и запускает некоторый jQuery. В то время как это работает в большинстве случаев, я нахожу, что иногда случается, что onBlur не запускается, и когда я возвращаюсь на страницу, тайминги "застроены", и вращения сходят с ума.

Я не могу определить причину, почему это происходит иногда, а не на других.

Мой вопрос: есть ли проблемы с моим кодом, и есть ли у кого-нибудь лучшее предложение для "паузы" setInterval, когда окно браузера не в фокусе?

Спасибо

Ответ 1

Попробуйте что-то вроде этого:

var myInterval;
var interval_delay = 500;
var is_interval_running = false; //Optional

$(document).ready(function () {
    $(window).focus(function () {
        clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
        if  (!is_interval_running) //Optional
            myInterval = setInterval(interval_function, interval_delay);
    }).blur(function () {
        clearInterval(myInterval); // Clearing interval on window blur
        is_interval_running = false; //Optional
    });
});

interval_function = function () {
     is_interval_running = true; //Optional
     // Code running while window is in focus
}

Некоторые тесты, выполненные в IE9 и FF6

Ответ 2

Непосредственно внутри setInterval поместите чек, чтобы увидеть, сфокусирован ли документ. Интервал продолжит стрельбу, как обычно, но код внутри будет выполняться только в том случае, если документ сфокусирован. Если окно размыто и затем переориентировано, интервал будет продолжать сохранять время, но document.hasFocus() был false в течение этого времени, поэтому нет необходимости, чтобы браузер "догонял", выполняя блок кода несколько раз, когда фокус восстанавливается.

var timePerInterval = 7000;
$(document).ready(function() {
    setInterval(function(){
        if ( document.hasFocus() ) {
            // code to be run every 7 seconds, but only when tab is focused
        }
    }, timePerInterval );
});