Skip to content

Instantly share code, notes, and snippets.

@benhodgson
Created November 6, 2011 12:59
Show Gist options
  • Select an option

  • Save benhodgson/1342840 to your computer and use it in GitHub Desktop.

Select an option

Save benhodgson/1342840 to your computer and use it in GitHub Desktop.

Revisions

  1. benhodgson revised this gist Nov 6, 2011. 1 changed file with 24 additions and 24 deletions.
    48 changes: 24 additions & 24 deletions subdued.js
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,15 @@
    // Hey, @addyosmani!
    // Hey, @addyosmani! Here's my #protip.

    // Of all the JavaScript I've written in the past year, this is definitely
    // my favourite. It uses some of JavaScript's awesome functional features
    // (namely closure and functions as first-class objects) to create a clean
    // interface for building specific event listeners from a general form.

    // This particular snippet allows you to "subdue" the behaviour of some of
    // the more excitable DOM events such as scroll and resize. With scroll, for
    // example, your event listener will be called up to once for *every pixel*
    // scrolled. Sometimes you just want to know when the scrolling starts and
    // ends.
    // This particular snippet allows you to "subdue" the behaviour of some of
    // the more excitable DOM events such as scroll and resize. With scroll, for
    // example, your event listener will be called up to once for *every pixel*
    // scrolled. Sometimes you just want to know when the scrolling starts and
    // ends.

    // The `subdued` function below takes (optionally) two functions. The first is
    // called when a stream of events starts, the second is called when the stream
    @@ -18,30 +18,30 @@
    // event listener, and passes the relevant event context to the callbacks.

    function subdued (cbStart, cbEnd, minInterval) {
    var timeout;
    minInterval = minInterval || 200; // default 200ms
    return function () {
    var eventArgs = Array.prototype.slice.call(arguments),
    eventThis = this;
    // timeout not set? call the start callback
    !timeout && cbStart && cbStart.apply(eventThis, eventArgs);
    // another event within timeout period; cancel the scheduled `cbEnd` call
    clearTimeout(timeout);
    timeout = setTimeout(function () {
    // If you've got here, then it's been `minInterval` milliseconds
    // since the last event. Congratulations! Call `cbEnd`.
    timeout = undefined;
    cbEnd && cbEnd.apply(eventThis, eventArgs);
    }, minInterval);
    };
    var timeout;
    minInterval = minInterval || 200; // default 200ms
    return function () {
    var eventArgs = Array.prototype.slice.call(arguments),
    eventThis = this;
    // timeout not set? call the start callback
    !timeout && cbStart && cbStart.apply(eventThis, eventArgs);
    // another event within timeout period; cancel the scheduled `cbEnd` call
    clearTimeout(timeout);
    timeout = setTimeout(function () {
    // If you've got here, then it's been `minInterval` milliseconds
    // since the last event. Congratulations! Call `cbEnd`.
    timeout = undefined;
    cbEnd && cbEnd.apply(eventThis, eventArgs);
    }, minInterval);
    };
    };

    function scrollStart () {
    console.log("scrolling started");
    console.log("scrolling started");
    };

    function scrollEnd () {
    console.log("scrolling ended");
    console.log("scrolling ended");
    };

    document.addEventListener('scroll', subdued(scrollStart, scrollEnd), true);
  2. benhodgson created this gist Nov 6, 2011.
    47 changes: 47 additions & 0 deletions subdued.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    // Hey, @addyosmani!

    // Of all the JavaScript I've written in the past year, this is definitely
    // my favourite. It uses some of JavaScript's awesome functional features
    // (namely closure and functions as first-class objects) to create a clean
    // interface for building specific event listeners from a general form.

    // This particular snippet allows you to "subdue" the behaviour of some of
    // the more excitable DOM events such as scroll and resize. With scroll, for
    // example, your event listener will be called up to once for *every pixel*
    // scrolled. Sometimes you just want to know when the scrolling starts and
    // ends.

    // The `subdued` function below takes (optionally) two functions. The first is
    // called when a stream of events starts, the second is called when the stream
    // stops. The third argument is the time in milliseconds used to determine the
    // end of the stream. `subdued` returns a function that can be used as an
    // event listener, and passes the relevant event context to the callbacks.

    function subdued (cbStart, cbEnd, minInterval) {
    var timeout;
    minInterval = minInterval || 200; // default 200ms
    return function () {
    var eventArgs = Array.prototype.slice.call(arguments),
    eventThis = this;
    // timeout not set? call the start callback
    !timeout && cbStart && cbStart.apply(eventThis, eventArgs);
    // another event within timeout period; cancel the scheduled `cbEnd` call
    clearTimeout(timeout);
    timeout = setTimeout(function () {
    // If you've got here, then it's been `minInterval` milliseconds
    // since the last event. Congratulations! Call `cbEnd`.
    timeout = undefined;
    cbEnd && cbEnd.apply(eventThis, eventArgs);
    }, minInterval);
    };
    };

    function scrollStart () {
    console.log("scrolling started");
    };

    function scrollEnd () {
    console.log("scrolling ended");
    };

    document.addEventListener('scroll', subdued(scrollStart, scrollEnd), true);