Событие, когда пользователь прекращает прокрутку - PullRequest
49 голосов
/ 13 сентября 2010

Я хотел бы сделать некоторые интересные вещи jQuery, когда пользователь прокручивает страницу. Но я понятия не имею, как решить эту проблему, поскольку существует только метод scroll ().

Есть идеи?

Ответы [ 8 ]

66 голосов
/ 13 сентября 2010

Вы можете задать для scroll() тайм-аут, который будет перезаписываться при каждой прокрутке пользователя.Таким образом, когда он останавливается через определенное количество миллисекунд, ваш скрипт запускается, но если он прокручивает между тем, счетчик снова запускается, и скрипт будет ждать, пока он снова не закончит прокрутку.

Обновление:

Поскольку этот вопрос снова получил какое-то действие, я подумал, что я мог бы также обновить его с расширением jQuery, которое добавляет событие scrollEnd

// extension:
$.fn.scrollEnd = function(callback, timeout) {          
  $(this).scroll(function(){
    var $this = $(this);
    if ($this.data('scrollTimeout')) {
      clearTimeout($this.data('scrollTimeout'));
    }
    $this.data('scrollTimeout', setTimeout(callback,timeout));
  });
};

// how to call it (with a 1000ms timeout):
$(window).scrollEnd(function(){
    alert('stopped scrolling');
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div style="height: 200vh">
  Long div
</div>
59 голосов
/ 27 сентября 2012

Вот простой пример использования setTimeout для запуска функции, когда пользователь прекращает прокрутку:

(function() {        
    var timer;
    $(window).bind('scroll',function () {
        clearTimeout(timer);
        timer = setTimeout( refresh , 150 );
    });
    var refresh = function () { 
        // do stuff
        console.log('Stopped Scrolling'); 
    };
})();

Таймер очищается во время срабатывания события прокрутки.Как только прокрутка останавливается, активируется функция обновления.

Или как плагин:

$.fn.afterwards = function (event, callback, timeout) {
    var self = $(this), delay = timeout || 16;

    self.each(function () { 
        var $t = $(this);
        $t.on(event, function(){
            if ($t.data(event+'-timeout')) {
                clearTimeout($t.data(event+'-timeout'));
            }
            $t.data(event + '-timeout', setTimeout(function () { callback.apply($t); },delay));
        })
    });
    return this;
};

Чтобы вызвать обратный вызов после 100 мс последнего события прокрутки в div (с пространством имен):

$('div.mydiv').afterwards('scroll.mynamespace', function(e) {
        // do stuff when stops scrolling
        $(this).addClass('stopped');
    }, 100
);

Я использую это для прокрутки и изменения размера.

10 голосов
/ 01 марта 2013

Вот еще одно более общее решение, основанное на тех же упомянутых идеях:

var delayedExec = function(after, fn) {
    var timer;
    return function() {
        timer && clearTimeout(timer);
        timer = setTimeout(fn, after);
    };
};

var scrollStopper = delayedExec(500, function() {
    console.log('stopped it');
});

document.getElementById('box').addEventListener('scroll', scrollStopper);
2 голосов
/ 29 января 2014

Почему так сложно? Как указывается в документации, это http://jsfiddle.net/x3s7F/9/ работает!

$('.frame').scroll(function() {
 $('.back').hide().fadeIn(100);
}

http://api.jquery.com/scroll/.


Примечание: Событие scroll в Windows Chrome отличается от всех остальных. Вам нужно быстро прокрутить, чтобы получить такой же результат, как, например, в. FF. Посмотрите на https://liebdich.biz/back.min.js функцию "X".

Некоторые результаты моего how many ms a scroll event теста:

  • Safari, Mac FF, Mac Chrome: ~ 16 мсек события.
  • Windows FF: ~ 19мс событие.
  • Windows Chrome: до ~ 130 мс, при медленной прокрутке.
  • Internet Explorer: до ~ 110 мс для события.

http://jsfiddle.net/TRNCFRMCN/1Lygop32/4/.

1 голос
/ 07 февраля 2017

Мне нужно было реализовать событие onScrollEnd , о котором я тоже слышал.Идея использования таймера работает для меня.

Я реализую это, используя Шаблон модуля JavaScript :

var WindowCustomEventsModule = (function(){

    var _scrollEndTimeout = 30;

    var _delayedExec = function(callback){
        var timer;
        return function(){
            timer && clearTimeout(timer);
            timer = setTimeout(callback, _scrollEndTimeout);
        }
    };

    var onScrollEnd = function(callback) { 
        window.addEventListener('scroll', _delayedExec(callback), false);         
    };

    return {
        onScrollEnd: onScrollEnd
    }
})();

// usage example
WindowCustomEventsModule.onScrollEnd(function(){
    //
    // do stuff
    //
});

Надеюсь, это кого-то поможет / вдохновит

1 голос
/ 30 ноября 2016

Есть функции scrollstart и scrollstop, которые являются частью jquery mobile.

Пример использования scrollstop:

$(document).on("scrollstop",function(){
   alert("Stopped scrolling!");
});

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 09 февраля 2012

Я вытащил некоторый код из быстрой части, которую я собрал вместе, что делает это в качестве примера (обратите внимание, что scroll.chain - это объект, содержащий два массива start и end, которые являются контейнерами для функций обратного вызова). Также обратите внимание, что я использую jQuery и подчеркивание здесь.

$('body').on('scroll', scrollCall);
scrollBind('end', callbackFunction);
scrollBind('start', callbackFunction);

var scrollCall = function(e) {
    if (scroll.last === false || (Date.now() - scroll.last) <= 500) {
        scroll.last = Date.now();
        if (scroll.timeout !== false) {
            window.clearTimeout(scroll.timeout);
        } else {
            _(scroll.chain.start).each(function(f){
                f.call(window, {type: 'start'}, e.event);
            });
        }
        scroll.timeout = window.setTimeout(self.scrollCall, 550, {callback: true, event: e});
        return;
    }
    if (e.callback !== undefined) {
        _(scroll.chain.end).each(function(f){
            f.call(window, {type: 'end'}, e.event);
        });
        scroll.last = false;
        scroll.timeout = false;
    }
};

var scrollBind = function(type, func) {
    type = type.toLowerCase();
    if (_(scroll.chain).has(type)) {
        if (_(scroll.chain[type]).indexOf(func) === -1) {
            scroll.chain[type].push(func);
            return true;
        }
        return false;
    }
    return false;
}
0 голосов
/ 13 сентября 2010

Нет такого события, как «scrollEnd».Я рекомендую проверять значение, возвращаемое scroll() время от времени (скажем, 200 мс), используя setInterval, и записывать дельту между текущим и предыдущим значением.Если дельта становится равной нулю, вы можете использовать ее как событие.

...