Skip to content

Instantly share code, notes, and snippets.

@benhodgson
Created November 6, 2011 12:59
Show Gist options
  • Save benhodgson/1342840 to your computer and use it in GitHub Desktop.
Save benhodgson/1342840 to your computer and use it in GitHub Desktop.
// 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.
// 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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment