Monday, April 14, 2008

JQuery Time-Delay Event Binding Plugin

Just to get a sense of how hard it would be I decided to write a plugin for JQuery I didn't see in the core. Basically this is a the same thing as the .bind function for JQuery except that it takes a timing parameter. How is this useful? Say you want do something 'onclick' or 'onchange' except you want to wait X milliseconds first. Perfect for an autocomplete ('onkeyup' I guess you'd use).

I have to say, I really like the JQuery programming model, and I think the author has really hit on something special. The plugin structure lets me write something that encapsulates state, and at the same time gives me a way to use it as if it were a static function. Pow.

Without further ado:

Update [12/10/2008]: The original version of this script didn't pass in the event object like JQuery's event binding. This has now been corrected. Invocation of the plugin stays the same.

----
Javascript:

(function($){
/**
* jQuery delayed event execution.
*/
$.fn.delay = function(options) {
var timer;
var delayImpl = function(eventObj) {
if (timer != null) {
clearTimeout(timer);
}
var newFn = function() {
options.fn(eventObj);
};
timer = setTimeout(newFn, options.delay);
}

return this.each(function() {
var obj = $(this);
obj.bind(options.event, function(eventObj) {
delayImpl(eventObj);
});
});
};
})(jQuery);

----

Usage:

$(document).ready(function() {
$('#typeinme').delay({
delay: 500,
event: 'keyup',
fn: function(){
alert(this.value);
})
});
}

----
Html:

<form action="#" method="get">
<input id="typeinme" name="station"></input>
</form>

14 comments:

Ivan said...

Am I retarded? Blogspot sucks for formatting code. Gonna have to look into this.

temhawk said...

LoL

tabino said...

hi, I need exactly what you are mentioning. I have a search() function that at the onclick event search in teh database and show me some records on the page. I have to delay the search and associate it to the onkeyup event of a text box so the user can type 3-4 characters before to start a real time search. How can I do this? sorry, Im not a great expert of Jquery Tnx a lot

rspring said...

Is there a way to clearTimeout for something once it's set?

Anonymous said...

google "hoverintent" - stable and configurable.

Anonymous said...

This was very helpful, thanks for posting.

Nanda Sunu dasa said...

I like it, but I lose context of the original element.

Bouke Versteegh said...

Great script. I adapted it to pass the object itself as the second argument.

The code is badly formatted here, but you can also change it manually:

Replace the line:
var delayImpl = function(eventObj) {
with:
var delayImpl = function(eventObj, obj) {

and replace
options.fn(eventObj);
with:
options.fn(eventObj, obj);

and replace
delayImpl(eventObj);
with:
delayImpl(eventObj, this);


You can then do something like:

$('#typeinme, #typeinme2').delay( {
event: 'keyup',
delay: 500,
fn: function( e, obj ) {
alert('you pressed key: ' + e.which);
alert('in object: ' + obj);
}

}

//-----snippet----//
(function($){
/**
* jQuery delayed event execution.
*/
$.fn.delay = function(options) {
var timer;
var delayImpl = function(eventObj, obj) {
if (timer != null) {
clearTimeout(timer);
}
var newFn = function() {
options.fn(eventObj, obj);
};
timer = setTimeout(newFn, options.delay);
}

return this.each(function() {
var obj = $(this);
obj.bind(options.event, function(eventObj) {
delayImpl(eventObj, this);
});
});
};
})(jQuery);

Anonymous said...

Many thanks... code worked like a charm for a search function with 4 separate search fields. Thanks!

123 123 said...

Great blog you got here. I'd like to read something more concerning that theme. Thnx for sharing that information.
Joan Stepsen
Escorts Cyprus

pettera said...

(function($) {
/**
* jQuery delayed event execution.
*/
$.fn.delay = function(options) {
var timer;
var delayImpl = function(domElem,eventObj) {
if (timer != null) {
clearTimeout(timer);
}
var newFn = function() {
options.fn.call(domElem, eventObj);
};
timer = setTimeout(newFn, options.delay);
}

return this.each(function() {
var obj = $(this);
obj.bind(options.event, function(eventObj) {
delayImpl(this,eventObj);
});
});
};
})(jQuery);

Did some minor changes so the 'this' object is the same as i would have been in the standard event..

rorra said...

Nice post!!!!

I was looking for a easy delayed event for jquery, and it was a great function to add to an application I'm developing.

Thank you for sharing :)

Anonymous said...

Interesting article you got here. It would be great to read a bit more
concerning that matter. Thanx for sharing that data.
Joan
Kiev escort service

Anonymous said...

This doesn't support delegated events (new to jQuery 1.7) or sending the function any data when it's triggered.

Check out this method which supports delegated events, namespaces, sending data, etc.

http://www.theloveofcode.com/jquery/delayed/