jQuery Edge: New Special Event Hooks
These Special Event hooks were changed in 1.4.2. Check out this blog post to see the details about the change.
In jQuery 1.3.3 1.4 there are two new special event hooks: add
and remove
. These two hooks, unlike setup
and teardown
, are called for each event being bound. The add
hook receives the handler, data, and namespaces as arguments. The remove
hook receives the data and namespaces as arguments. The add
and remove
hooks enable the creation of more complex, even customizable, events.
If you haven’t done so, I recommend reading the Special Events blog post which explains what special events are and how to use them. For the following example I assume you already understand the concept of special events in jQuery.
As an example I’m going to build a new special event called “multiclick”. This event tracks clicks on an element and fires at a given threshold or number of clicks. The required number of clicks will be customizable per a handler.
First, here is how you’d use the multiclick event.
$('div')
.bind("multiclick", { threshold: 5 }, function( event ) {
alert( "Clicked 5 times" );
})
.bind("multiclick", { threshold: 3 }, function( event ) {
alert( "Clicked 3 times" );
});
Now lets build it. The skeleton of the multiclick special event looks like this.
jQuery.event.special.multiclick = {
add: function( handler, data, namespaces ) {
// called for each bound handler
},
setup: function( data, namespaces ) {
// called once per an element
},
remove: function( namespaces ) {
// called for each bound handler
},
teardown: function( namespaces ) {
// called once per an element
},
handler: function( event ) {
}
};
Behind the scenes we’ll need to use a normal click event. We’ll use the setup
hook to bind the initial click event to track the actual clicks. The handler
method will be used to properly trigger the multiclick events. Once all the multiclick events are removed, the teardown
hook will be triggered. We’ll need to unbind the the click event we used to track the clicks in the setup
hook. Here is the updated multiclick event.
jQuery.event.special.multiclick = {
add: function( handler, data, namespaces ) {
// called for each bound handler
},
setup: function( data, namespaces ) {
jQuery( this ).bind( "click", jQuery.event.special.multiclick.handler );
},
remove: function( namespaces ) {
// called for each bound handler
},
teardown: function( namespaces ) {
jQuery( this ).unbind( "click", jQuery.event.special.multiclick.handler );
},
handler: function( event ) {
// set correct event type
event.type = "multiclick";
// trigger multiclick handlers
jQuery.event.handle.apply( this, arguments );
}
};
Next we need to make sure the bound function to a multiclick event isn’t fired until it reaches the number of clicks specified. We’ll utilize the add
hook for this. The add
hook has the ability to return a function which will take the place of the provided handler. This is a powerful feature and allows us to do all sorts of fun things with special events. In the case of the multiclick event we are going to return a new function that calls the given handler after the specified number of clicks. Here is the add
hook.
jQuery.event.special.multiclick = {
add: function( handler, data, namespaces ) {
// get the required number of clicks from data
var threshold = data && data.threshold || 1,
// number of clicks
clicks = 0;
// return a new function that will become the handler
return function( event ) {
// increase number of clicks
clicks += 1;
if ( clicks === threshold ) {
// required number of clicks reached, reset
clicks = 0;
// call the actual supplied handler
handler.apply( this, arguments );
}
}
},
...
};
The add
hook makes use of closures to keep track of the required number of clicks (threshold), the actual number of clicks, and the handler to be called once the required number of clicks is reached. The jQuery event system keeps everything in tact so that when you call unbind with the same named function that you supplied to bind, it still unbinds it as expected.
It ends up that we don’t actually need to use the remove
hook for this special event, so we’ll just remove it. Thats it. The multiclick special event is done.
jQuery.event.special.multiclick = {
add: function( handler, data, namespaces ) {
// get the required number of clicks from data
var threshold = data && data.threshold || 1,
// number of clicks
clicks = 0;
// return a new function that will become the handler
return function( event ) {
// increase number of clicks
clicks += 1;
if ( clicks === threshold ) {
// required number of clicks reached, reset
clicks = 0;
// call the actual supplied handler
handler.apply( this, arguments );
}
}
},
setup: function( data, namespaces ) {
jQuery( this ).bind( "click", jQuery.event.special.multiclick.handler );
},
teardown: function( namespaces ) {
jQuery( this ).unbind( "click", jQuery.event.special.multiclick.handler );
},
handler: function( event ) {
// set correct event type
event.type = "multiclick";
// trigger multiclick handlers
jQuery.event.handle.apply( this, arguments );
}
};
Thanks
Thanks to Mike Helgeson who helped evolve the special events API to include these two hooks. He also has a handful of special events that he has created: drag, drop, hover, and wheel.
If you knew about the specialAll
event hook, it has been removed in favor of using these two extra hooks.