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

@ -12,14 +12,14 @@ jQuery.event = {
// around, causing it to be cloned in the process // around, causing it to be cloned in the process
if ( jQuery.browser.msie && element.setInterval != undefined ) if ( jQuery.browser.msie && element.setInterval != undefined )
element = window; element = window;
// Make sure that the function being executed has a unique ID // Make sure that the function being executed has a unique ID
if ( !handler.guid ) if ( !handler.guid )
handler.guid = this.guid++; handler.guid = this.guid++;
// if data is passed, bind to handler // if data is passed, bind to handler
if( data != undefined ) { if( data != undefined ) {
// Create temporary function pointer to original handler // Create temporary function pointer to original handler
var fn = handler; var fn = handler;
// Create unique handler function, wrapped around original handler // Create unique handler function, wrapped around original handler
@ -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,7 +112,9 @@ 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] )
delete events[type][handler]; // Handle the removal of namespaced events
if ( !parts[1] || events[type][handler].type == parts[1] )
delete events[type][handler];
// remove generic event handler if no more handlers exist // remove generic event handler if no more handlers exist
for ( ret in events[type] ) break; for ( ret in events[type] ) break;
@ -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,14 +203,17 @@ jQuery.event = {
args[0].handler = c[j]; args[0].handler = c[j];
args[0].data = c[j].data; args[0].data = c[j].data;
var tmp = c[j].apply( this, args ); // Filter the functions by class
if ( !parts[1] || c[j].type == parts[1] ) {
var tmp = c[j].apply( this, args );
if ( val !== false ) if ( val !== false )
val = tmp; val = tmp;
if ( tmp === false ) { if ( tmp === false ) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
}
} }
} }

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() {