Подтвердить что ты не робот

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

У меня есть ползунок jQuery на моем сайте, и код, идущий на следующий слайд, находится в функции, называемой nextImage. Я использовал setInterval для запуска моей функции по таймеру, и он делает именно то, что я хочу: он запускает мои слайды по таймеру. НО, если я перейду на сайт в Chrome, переключитесь на другую вкладку и верните ее, ползунок будет непрерывно проходить через слайды, пока он не "поймает". Кто-нибудь знает, как это исправить. Ниже приведен мой код.

setInterval(function() {
nextImage();
}, 8000);
4b9b3361

Ответ 1

Как определить, когда вкладка сосредоточена или нет в Chrome с помощью Javascript?

window.addEventListener('focus', function() {
    document.title = 'focused';
},false);

window.addEventListener('blur', function() {
    document.title = 'not focused';
},false);

Чтобы применить к вашей ситуации:

var autopager;
function startAutopager() {
    autopager = window.setInterval(nextImage, 8000);
}
function stopAutopager() {
    window.clearInterval(autopager);
}

window.addEventListener('focus', startAutopager);    
window.addEventListener('blur', stopAutopager);

Обратите внимание, что в последней версии Chromium имеется либо ошибка, либо "функция", которая делает ее менее надежной, требуя, чтобы пользователь нажал хотя бы один раз в любом месте окна. См. Связанный вопрос выше для деталей.

Ответ 2

Я пишу ответ здесь: Как заставить setInterval работать, когда вкладка неактивна в Chrome?

Просто сделайте следующее:

setInterval(function() {
    $("#your-image-container").stop(true,true);
    nextImage();

}, 1000);

Неактивные вкладки браузера содержат некоторые функции setInterval или setTimeout. stop (true, true) - остановит все буферизованные события и выполнит незаметно только последнюю анимацию.

Теперь метод window.setTimeout() зажимает для отправки не более одного тайм-аута в секунду на неактивных вкладках. Кроме того, теперь он захватывает вложенные таймауты до наименьшего значения, допускаемого спецификацией HTML5: 4 мс (вместо 10 мс, которые он использовал для фиксации).

Ответ 3

На ум приходит мысль:


Идея № 1

Вы можете сделать так, чтобы короткий пакет был idempotent. Например, вы можете сказать:

function now() {
    return (new Date()).getTime();
}

var autopagerInterval = 8000;

function startAutopager() {
    var startImage = getCurrentImageNumber();
    var startTime = now();

    var autopager = setInterval(
        function() {
            var timeSinceStart = now() - startTime();
            var targetImage = getCurrentImageNumber + Math.ceil(timeSinceStart/autopagerInterval);
            if (getCurrentImageNumber() != targetImage)
                setImageNumber(targetImage);  // trigger animation, etc.
        },
        autopagerInterval
    );
    return autopager;
}

Таким образом, даже если функция запускается 1000 раз, она будет выполняться всего за несколько миллисекунд и анимация только один раз.

note. Если пользователь покинет страницу и вернется, она будет прокручена. Возможно, это не то, что хочет исходный плакат, но я оставляю это решение, потому что иногда это то, что вы хотите.


Идея № 2

Еще один способ добавить idempotence (сохраняя при этом nextImage() функцию и не прокручивая ее в нижней части страницы) должен был установить функцию блокировки мьютекса, которая исчезает после секунды (очищается другим таймаутом), Таким образом, даже если функция setInterval вызывалась 1000 раз, запускался только первый экземпляр, а остальные ничего не делали.

var locked = false;
var autopager = window.setInterval(function(){
    if (!locked) {
        locked = true;
        window.setTimeout(function(){
            locked=false;
        }, 1000);
        nextImage();
    }
}, 8000);

изменить: это может не сработать, см. ниже


Идея № 3

Я пробовал следующий тест:

function f() {
    console.log((new Date()) + window.focus());
    window.setTimeout(f, 1000);
}
f();

Кажется, это указывает на то, что функция вызывается каждую секунду. Это странно... но я думаю, что это означает, что вызывающие вызовы вызываются, но что средство визуализации страниц отказывается обновлять страницу каким-либо графическим способом, пока вкладка не сфокусирована, задержка всех операций до тех пор, пока пользователь не вернется, но операции продолжаются свай вверх.

Также функция window.focus() не указывает, имеет ли фокус фокус; он ОТКРЫВАЕТ фокус на окно и, следовательно, не имеет значения.

Мы хотим, вероятно, так: Как определить, когда вкладка сосредоточена или нет в Chrome с помощью Javascript? - вы можете отключить свой интервал, когда окно теряет фокус (размытие) и reset, когда он получает фокус.

Ответ 4

Я точно не знаю, что происходит в вашей функции nextImage(), но у меня была аналогичная проблема. Я использовал анимацию() с setInterval() на слайдере изображения jQuery, который я создал, и я испытывал то же самое, что и вы, когда я переключился на другую вкладку и обратно. В моем случае функция animate() была поставлена ​​в очередь, поэтому, как только окно вернет фокус, слайдер сойдет с ума. Чтобы исправить это, я просто остановил функцию animate() из очереди.

Есть несколько способов сделать это. самый простой - с .stop(), но эта проблема и способы ее устранения задокументированы в документах jQuery. Проверьте эту страницу в нижней части под заголовком дополнительных примечаний: http://api.jquery.com/animate/

Ответ 5

Я столкнулся с подобной проблемой, так как этот код ниже работает отлично для меня.

            var t1= window.setInterval('autoScroll()', 8000);

    window.addEventListener('focus', function() {
        focused = true;
        window.clearInterval(t1);
        t1 = window.setInterval('autoScroll()', 8000);
    },false);

    window.addEventListener('blur', function() {
        focused = false;
        window.clearInterval(t1);
    },false)



function autoScroll()

    {

        if ( running == true){
            if ( focused = true){
                forwardSlide();
            }


        }

        else {

            running = true;

        }



    }

Ответ 6

Если вы используете слайдер изображения Soh Tanaka, просто добавьте это... чтобы решить проблему с Google Chrome:

$(".image_reel").stop(true, true).fadeOut(300).animate({ left: -image_reelPosition}, 500 ).fadeIn(300);

Обратите внимание на функцию .stop(). Игнорируйте затухание в и вне, что я использовал в моей версии

Спасибо