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.
UK EVENTAttend ffconf.org 2024
The conference for people who are passionate about the web. 8 amazing speakers with real human interaction and content you can't just read in a blog post or watch on a tiktok!
£249+VAT - reserve your place today
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));
There's also a simple rate throttled function in the comments below, that fires on every nth message - though I'd be inclined to tweak it to ensure the first message is delivered