Событие прокрутки jQuery запускается дважды

Я работаю над созданием бесконечной функции прокрутки для страницы и сталкиваюсь с проблемой, когда кажется, что $( window ).scroll() функция срабатывает дважды. Я встречал похожие вопросы о stackru, но, похоже, они связаны с быстрой прокруткой и отсутствием чего-либо, что могло бы проверить, был ли запрос уже отправлен. Вот код, с которым я сейчас работаю, я думаю, что это что-то простое, что мне здесь не хватает.

var loading = false;
var scrollcount = 0;

$( window ).scroll( function(){
    scrollcount++;
    var scrolling = $( document ).scrollTop();
    var position = $( "#ajax-load" ).offset();
    if( scrolling + $( window ).height() > position.top - 200 && loading == false ){
        console.log( loading ); //returns 2 falses
        console.log( scrollcount ); //returns 2 of the same number
        console.log( $( document ).scrollTop() ); //returns same number
        loading = true;
        $( "#ajax-load" ).css( "display", "block" );
        $.get( "url/to/my/script", info )
        .done( function( data ){
            //here's where the items are appended to the document
            setTimeout( function(){
                loading = false;
            }, 5000 );
        });
    }
});

То, что, когда я выхожу из системы с переменной scrollcount и возвращаюсь из scrollTop(), я получаю одно и то же число дважды, кажется, говорит мне, что событие по какой-то причине запускается дважды одновременно. Кажется, что если бы она стреляла дважды, один за другим, переменная загрузки была бы установлена ​​в ложь и не сработала бы во второй раз. Как я уже сказал, я представляю, что это что-то очень простое, что я скучаю. Спасибо за вашу помощь!

3 ответа

Мое первое предположение - у вас есть обработчик событий, примененный дважды, где бы ни находился этот код.

Попробуйте добавить $(window).unbind('scroll'); до $ (окно).scroll

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

var timeout;

$(window).scroll(function() {
    clearTimeout(timeout);  
    timeout = setTimeout(function() {
        // do your stuff
    }, 50);
});

Используйте этот код.

Я возился с этим и попробовал некоторые из вышеупомянутых решений. Ни один из них не работает на 100% с основными браузерами для моего варианта использования (это был простой загрузчик с прокруткой). Чтобы избежать использования setTimeout и ТОЛЬКО выполнять определенную функцию в течение установленного времени, создайте этот литерал объекта функции:

var hlpr = {
        lastExec: new Date().getTime(),
        isThrottled: function (timeout) {
            if ((new Date().getTime() - this.lastExec) < timeout) {
                console.log('returned');
                return false;
            }
            this.lastExec = new Date().getTime();
            return true;
        }
};

А затем добавьте это к функции, которую вы привязали к своему событию прокрутки:

if (!hlpr.isThrottled(500))
     return;

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

Другие вопросы по тегам