If you've written any kind of validation on user input, like onkeypress
then you'll know that sometimes you want to throttle the amount of times your function runs. A good example of this is Ajax based username validation - you don't want to hit the server on every key press, because most users will be able to write their name in around 1/10th of a second, so you should throttle the ajax request until the input is dormant for 100ms.
So with a bit of magic JavaScript making use of the ever useful closure JavaScript offers, we can create a simple method to handle this for us:
function debounce(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
So if you were doing something with jQuery, like a key press validation, you would do this instead:
$('input.username').keypress(debounce(function (event) {
// do the Ajax request
}, 250));
The keyword this
is the input as you would expect, and all the correct arguments are passed to the event handle, i.e. it works the exact same way as you'd expect, except it only fires once the keypress
event is idle for 250ms (in this particular case).
Below is an actual throttle function, that fires a message every 250ms by default (rather than at the end of a burst of events):
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
So when you use this, moving the mouse around the example below, will echo out the tick on the first time you move, but then every 1 second until you stop moving the mouse:
$('body').on('mousemove', throttle(function (event) {
console.log('tick');
}, 1000));