[UPDATED: Wednesday, August 24, 2011 at 3:19:27 PM]
I was looking through the source code of Underscore.js this morning and notice it's implementation of _.throttle() contains two issues that bother me with most JavaScript-based throttle implementations I've seen:
Let's take a look at an example I posted on JSFiddle: http://jsfiddle.net/MNGpr/
Mouse your mouse from the top left of the "Results" frame to the bottom right. If you do this quickly (under the 1 second delay,) you'll notice that when the function executes it's based upon coordinates in the upper left of the screen—not where your cursor left off.
What I've been doing is using the following throttle() function in my code:
// limit a function to only firing once every XX ms var throttle = function (fn, delay, trail){ delay || (delay = 100); var last = 0, timeout, args, context, offset = (trail === false) ? 0 : delay; return function (){ // we subtract the delay to prevent double executions var now = +new Date, elapsed = (now - last - offset); args=arguments, context=this; function exec(){ // remove any existing delayed execution timeout && (timeout = clearTimeout(timeout)); fn.apply(context, args); last = now; } // execute the function now if( elapsed > delay ) exec(); // add delayed execution (this could execute a few ms later than the delay) else if( !timeout && trail !== false ) timeout = setTimeout(exec, delay); }; };
What this version does that differentiates it from the Underscore.js version is it:
To see the difference in behavior, check out the JSFiddle example using my version of throttle().
13 Comments
Comments for this entry have been disabled.