Событие прокрутки 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 мс.