Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created April 27, 2010 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cowboy/380755 to your computer and use it in GitHub Desktop.
Save cowboy/380755 to your computer and use it in GitHub Desktop.
/*!
* Prototype throttle / debounce - v1.1 - 4/27/2010
* http://benalman.com/projects/jquery-throttle-debounce-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function(window,proto,undefined){
// Internal method reference.
var throttle;
proto.debounce = function( delay, at_begin ) {
return throttle.call( this, !!at_begin, delay );
};
proto.throttle = throttle = function( debounce_mode, delay, no_trailing ) {
var callback = this,
// After wrapper has stopped being called, this timeout ensures that
// `callback` is executed at the proper times in `throttle` and `end`
// debounce modes.
timeout_id,
// Keep track of the last time `callback` was executed.
last_exec = 0;
// Handle non-debounce mode.
if ( typeof debounce_mode !== 'boolean' ) {
no_trailing = delay;
delay = debounce_mode;
debounce_mode = undefined;
}
// The `wrapper` function encapsulates all of the throttling / debouncing
// functionality and when executed will limit the rate at which `callback`
// is executed.
function wrapper() {
var that = this,
elapsed = +new Date() - last_exec,
args = arguments;
// Execute `callback` and update the `last_exec` timestamp.
function exec() {
last_exec = +new Date();
callback.apply( that, args );
};
// If `debounce_mode` is true (at_begin) this is used to clear the flag
// to allow future `callback` executions.
function clear() {
timeout_id = undefined;
};
if ( debounce_mode && !timeout_id ) {
// Since `wrapper` is being called for the first time and
// `debounce_mode` is true (at_begin), execute `callback`.
exec();
}
// Clear any existing timeout.
timeout_id && clearTimeout( timeout_id );
if ( debounce_mode === undefined && elapsed > delay ) {
// In throttle mode, if `delay` time has been exceeded, execute
// `callback`.
exec();
} else if ( no_trailing !== true ) {
// In trailing throttle mode, since `delay` time has not been
// exceeded, schedule `callback` to execute `delay` ms after most
// recent execution.
//
// If `debounce_mode` is true (at_begin), schedule `clear` to execute
// after `delay` ms.
//
// If `debounce_mode` is false (at end), schedule `callback` to
// execute after `delay` ms.
timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
}
};
// Return the wrapper function.
return wrapper;
};
})(this,Function.prototype);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment