Added namespaced events to bind, unbind, and trigger. This allows you to deal with event handlers of a specific "class" (great for plugins).

This commit is contained in:
John Resig 2007-09-03 14:53:09 +00:00
parent a5c319f922
commit 456f0fe598
2 changed files with 52 additions and 10 deletions

View file

@ -35,6 +35,11 @@ jQuery.event = {
handler.guid = fn.guid; handler.guid = fn.guid;
} }
// Namespaced event handlers
var parts = type.split(".");
type = parts[0];
handler.type = parts[1];
// Init the element's event structure // Init the element's event structure
if (!element.$events) if (!element.$events)
element.$events = {}; element.$events = {};
@ -82,6 +87,12 @@ jQuery.event = {
remove: function(element, type, handler) { remove: function(element, type, handler) {
var events = element.$events, ret, index; var events = element.$events, ret, index;
// Namespaced event handlers
if ( typeof type == "string" ) {
var parts = type.split(".");
type = parts[0];
}
if ( events ) { if ( events ) {
// type is actually an event object here // type is actually an event object here
if ( type && type.type ) { if ( type && type.type ) {
@ -101,6 +112,8 @@ jQuery.event = {
// remove all handlers for the given type // remove all handlers for the given type
else else
for ( handler in element.$events[type] ) for ( handler in element.$events[type] )
// Handle the removal of namespaced events
if ( !parts[1] || events[type][handler].type == parts[1] )
delete events[type][handler]; delete events[type][handler];
// remove generic event handler if no more handlers exist // remove generic event handler if no more handlers exist
@ -177,6 +190,10 @@ jQuery.event = {
// Empty object is for triggered events with no data // Empty object is for triggered events with no data
event = jQuery.event.fix( event || window.event || {} ); event = jQuery.event.fix( event || window.event || {} );
// Namespaced event handlers
var parts = event.type.split(".");
event.type = parts[0];
var c = this.$events && this.$events[event.type], args = Array.prototype.slice.call( arguments, 1 ); var c = this.$events && this.$events[event.type], args = Array.prototype.slice.call( arguments, 1 );
args.unshift( event ); args.unshift( event );
@ -186,6 +203,8 @@ jQuery.event = {
args[0].handler = c[j]; args[0].handler = c[j];
args[0].data = c[j].data; args[0].data = c[j].data;
// Filter the functions by class
if ( !parts[1] || c[j].type == parts[1] ) {
var tmp = c[j].apply( this, args ); var tmp = c[j].apply( this, args );
if ( val !== false ) if ( val !== false )
@ -196,6 +215,7 @@ jQuery.event = {
event.stopPropagation(); event.stopPropagation();
} }
} }
}
// Clean up added properties in IE to prevent memory leak // Clean up added properties in IE to prevent memory leak
if (jQuery.browser.msie) if (jQuery.browser.msie)

View file

@ -1,7 +1,7 @@
module("event"); module("event");
test("bind()", function() { test("bind()", function() {
expect(11); expect(15);
var handler = function(event) { var handler = function(event) {
ok( event.data, "bind() with data, check passed data exists" ); ok( event.data, "bind() with data, check passed data exists" );
@ -45,6 +45,28 @@ test("bind()", function() {
$("select").each(function(i){ $("select").each(function(i){
$(this).bind('change', i, selectOnChange); $(this).bind('change', i, selectOnChange);
}).trigger('change'); }).trigger('change');
reset();
$("#firstp").bind("click",function(e){
ok(true, "Normal click triggered");
});
$("#firstp").bind("click.test",function(e){
ok(true, "Namespaced click triggered");
});
// Trigger both bound fn (2)
$("#firstp").trigger("click");
// Trigger one bound fn (1)
$("#firstp").trigger("click.test");
// Remove only the one fn
$("#firstp").unbind("click.test");
// Trigger the remaining fn (1)
$("#firstp").trigger("click");
}); });
test("click()", function() { test("click()", function() {