jQuery / JavaScript: моя рекурсивная функция setTimeout ускоряется, когда вкладка становится неактивной - PullRequest
5 голосов
/ 08 июля 2011

У меня есть странная маленькая дилемма в этом плагине jQuery для создания слайд-шоу, который я создаю.

Ничего особенного, и код, который я написал на сегодняшний день, работает отлично, однако я заметил, что когда я покидаюсайт работает и переключитесь на новую вкладку и продолжите просмотр веб-страниц на этой другой вкладке (Chrome для Mac в моем случае) , что при возвращении на мой сайт вызов setTimeout, кажется, ускоряется ивместо того, чтобы ждать, пока таймер завершит запуск события, он срабатывает непрерывно.

Вот мой (упрощенный) код:

var timer;
var counter;
var slides; // collection of all targeted slides.

// animate to the next slide
function nextSlide() {

    // stop timer
    methods.stopTimer();

    // increase counter
    counter++;
    if ( counter > slides.length-1 ) { counter = 0; } // if counter is greater than the amount of slides, back to the start.

    // inner = container to be animated
    // in the complete callback restart the timer.
    inner.animate({
        'left': '-'+slides.eq( counter ).position().left
    }, {
        duration : settings.animationSpeed,
        easing  : 'easeInOutExpo',
        complete : startTimer()
    });


}
// timer functions.
function startTimer() {
    if ( timer === '' ) {
        timer = setTimeout( function() {
            nextSlide();
        } , 3000 );
    }
}
function stopTimer() {
    clearTimeout( timer );
    timer = '';
}

Итак, что должно произойтизаключается в том, что в конце анимации таймер снова подключается к другому вызову setTimeout, так что он превращается в непрерывное слайд-шоу (и это прекрасно работает, пока вы не покинете вкладку.

После того, как вы покинете вкладку ивернитесь на вкладку со слайд-шоу, и кажется, что таймер 3000 ms был сокращен для мгновенного вызова, и теперь, когда анимация заканчивается, следующий начинается без задержки на всехl.

Любые идеи о том, почему это происходит, и о том, как это можно решить, будут высоко оценены.

Спасибо за чтение,

Яннис

Ответы [ 2 ]

7 голосов
/ 08 июля 2011

Некоторые браузеры (например, Chrome) резко замедляют повторяющиеся таймеры, когда вкладка становится неактивной, а затем, когда вкладка снова становится активной, они пытаются «догнать», чтобы произошло то же количество фактических событий таймера. Все, что я могу придумать как обходной путь, это чтобы вы полностью остановили слайд-шоу, когда вкладка стала неактивной, и запустите ее снова, когда она стала активной.

2 голосов
/ 08 июля 2011

Вместо тайм-аутов вы пробовали интервалы?Также для того, чтобы он был рекурсивным, просто вызовите функцию nextSlide () в качестве собственного обратного вызова:

var counter = 1;

// animate to the next slide
function nextSlide() {

    // increase counter
    counter++;

    // if counter is greater than the amount of slides, back to the start.
    counter =  ( counter > slides.length-1 ) ? 0 : counter;

    // inner = container to be animated
    // in the complete callback restart the timer.
    inner.animate(
    {
        'left': '-' + slides.eq( counter ).position().left
    }, 
    {
        duration : settings.animationSpeed,
        easing  : 'easeInOutExpo',
        complete : nextSlide()
    });

}

Тогда нужно просто запустить и остановить интервал:

var slideshow;
function startSlideshow()
{
    slideshow = setInterval(nextSlide(),3000);
}

function stopSlideshow()
{
    clearInterval(slideshow);
    inner.stop();
}
...