if ( events ) {
// Unbind all events for the element
- if ( types == undefined )
+ if ( types == undefined || types[0] == "." )
for ( var type in events )
- this.remove( elem, type );
+ this.remove( elem, type + (types || "") );
else {
// types is actually an event object here
if ( types.type ) {
// Clone the incoming data, if any
data = jQuery.makeArray(data || []);
+ if ( type.indexOf("!") >= 0 ) {
+ type = type.slice(0, -1);
+ var exclusive = true;
+ }
+
// Handle a global trigger
if ( !elem ) {
// Only trigger if we've ever bound an event for it
// Enforce the right trigger type
data[0].type = type;
+ if ( exclusive )
+ data[0].exclusive = true;
// Trigger the event
if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
// Handle triggering of extra function
if ( extra && jQuery.isFunction( extra ) ) {
// call the extra function and tack the current return value on the end for possible inspection
- ret = extra.apply( elem, data.concat( val ) );
+ ret = extra.apply( elem, val == null ? data : data.concat( val ) );
// if anything is returned, give it precedence and have it overwrite the previous value
if (ret !== undefined)
val = ret;
args[0].data = handler.data;
// Filter the functions by class
- if ( !parts[1] || handler.type == parts[1] ) {
+ if ( !parts[1] && !event.exclusive || handler.type == parts[1] ) {
var ret = handler.apply( this, args );
if ( val !== false )