16
votes

I would like to know if it is possible to fire an event after the scrolling of a page, when using the scrollbar or mouse-wheel (or with a swipe on a touch device).

Basically, I'd like to detect when the user has stopped scrolling so I can then AJAX-load, rather than loading while scrolling.

It seems that jQuery's .scroll() is firing every time a user scrolls, and it seems clunky to have an event fire all the time. Is there such thing as .onScrollAfter(), synonymous to the .onMouseUp()?

I'd like to know whether this is possible (or if a function already exists) without using a framework, though I would consider one; especially jQuery.

3

3 Answers

8
votes

This event does not exist. You can emulate it by using timeouts:

Example (concept code):

(function() {
    var timer;
    /* Basic "listener" */
    function scroll_finish(ev) {
        clearTimeout(timer);
        timer = setTimeout(scroll_finished, 200, ev);
        //200ms. Too small = triggered too fast. Too high = reliable, but slow
    }
    window.onscroll = scroll_finish; // Or addEventListener, it's just a demo

    // Fire "events"
    var thingey = [];
    function scroll_finished(ev) {
        // Function logic
        for (var i=0; i<thingey.length; i++) {
            thingey[i](ev);
        }
    }
    // Add listener
    window.addScrollListener = function(fn) {
        if (typeof fn  === 'function') {
            thingey.push(fn);
        } else {
           throw TypeError('addScrollListener: First argument must be a function.');
        }
    }
    window.removeScrollListener = function(fn) {
        var index = thingey.indexOf(fn);
        if (index !== -1) thingey.splice(index, 1);
    }
})();
3
votes

Thought I would add this as an answer even though it's old. The event you are trying to recreate I believe is synonymous to debounce. This is available in underscore.js

debounce_.debounce(function, wait, [immediate]) Creates and returns a new debounced version of the passed function which will postpone its execution until after wait milliseconds have elapsed since the last time it was invoked. Useful for implementing behavior that should only happen after the input has stopped arriving. For example: rendering a preview of a Markdown comment, recalculating a layout after the window has stopped being resized, and so on.

So it will wait after your last execution of the specific event. if you do not want a delay, you can just specify 0. David Walsh has a pretty nice implementation you can include in any project.

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

Which you can go ahead adding by doing

var myEfficientFn = debounce(function() {
    // All the taxing stuff you do
}, 250);

window.addEventListener('scroll', myEfficientFn);
2
votes

Description

You can use the nice jQuery plugin Special scroll events for jQuery by James Padoley.

Works really great.

Check out the page and this jsFiddle Demonstration (Just scroll ;))

More Information