davestewart
10/13/2012 - 9:50 AM

jQuery throttle plugin - allows you to call a custom function on an element multiple times without flooding

jQuery throttle plugin - allows you to call a custom function on an element multiple times without flooding

/*
* Project:		jQuery throttle plugin
* Description:	Allows you to call a custom function on an element multiple times without flooding
* Author:		Dave Stewart
* License:		MIT
* Usage:		$(element).throttle(function(){console.log(this);}, 'log');
*/

;(function ( $, window, undefined ) {
	
	// Create the defaults once
		var pluginName	= 'throttle';
		var dataName	= 'plugin_' + pluginName;
		var document	= window.document;

	// plugin constructor
		function Plugin(element)
		{
			this.element	= element;
			this._name		= pluginName;
			this.ids		= {};
		}

	// plugin prototype
		Plugin.prototype =
		{
			/**
			 * Main execution function, called in the jQuery each loop
			 * @param	{Function}		callback	The function to call when the timeout limit is reached
			 * @param	{String}		name		An optional name for the callback. Using unique names allows for multiple callbacks to be attached to the same element
			 * @param	{Number}		delay		A delay in milliseconds that the callback should wait until firing, or being replaced. Defaults to 100
			 */
			init:function (callback, name, delay)
			{
				// parameters
					name		= name || 'callback';
					delay		= delay || 100;
					
				// clear any old callbacks
					var id = this.ids[name];
					if(id)
					{
						clearTimeout(id);
					}
					
				// add / replace the new callback
					if(callback)
					{
						this.ids[name] = setTimeout(callback, delay);
					}
					
			}
		}
		
		$.fn[pluginName] = function ( callback, name, delay )
		{
			return this.each(function (){
				
				// instantiate a new copy the first time only
					var plugin = $.data(this, dataName);
					if ( ! plugin )
					{
						plugin = $.data(this, dataName, new Plugin(this));
					}

				// otherwise, run the plugin					
					plugin.init(callback, name, delay);
			});
		};

}(jQuery, window));