Commit 81189178 authored by Brandon Aaron's avatar Brandon Aaron

.bind() now accepts an optional thisObject as the last argument which is used...

.bind() now accepts an optional thisObject as the last argument which is used to change the value of this in event callbacks. fixes #3699
parent 8f042d8b
...@@ -374,8 +374,13 @@ jQuery.event = { ...@@ -374,8 +374,13 @@ jQuery.event = {
return event; return event;
}, },
proxy: function( fn, proxy ) { proxy: function( fn, proxy, thisObject ) {
proxy = proxy || function() { return fn.apply( this, arguments ); }; if ( proxy !== undefined && !jQuery.isFunction( proxy ) ) {
thisObject = proxy;
proxy = undefined;
}
// FIXME: Should proxy be redefined to be applied with thisObject if defined?
proxy = proxy || function() { return fn.apply( thisObject !== undefined ? thisObject : this, arguments ); };
// Set the guid of unique handler to the same of original handler, so it can be removed // Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
// So proxy can be declared as an argument // So proxy can be declared as an argument
...@@ -509,19 +514,35 @@ jQuery.each({ ...@@ -509,19 +514,35 @@ jQuery.each({
}); });
jQuery.fn.extend({ jQuery.fn.extend({
bind: function( type, data, fn ) { bind: function( type, data, fn, thisObject ) {
return type === "unload" ? this.one(type, data, fn) : this.each(function() { if ( jQuery.isFunction( data ) ) {
jQuery.event.add( this, type, fn || data, fn && data ); if ( fn !== undefined ) {
thisObject = fn;
}
fn = data;
data = undefined;
}
fn = thisObject === undefined ? fn : jQuery.event.proxy( fn, thisObject );
return type === "unload" ? this.one(type, data, fn, thisObject) : this.each(function() {
jQuery.event.add( this, type, fn, data, thisObject );
}); });
}, },
one: function( type, data, fn ) { one: function( type, data, fn, thisObject ) {
var one = jQuery.event.proxy( fn || data, function( event ) { if ( jQuery.isFunction( data ) ) {
if ( fn !== undefined ) {
thisObject = fn;
}
fn = data;
data = undefined;
}
fn = thisObject === undefined ? fn : jQuery.event.proxy( fn, thisObject );
var one = jQuery.event.proxy( fn, function( event ) {
jQuery( this ).unbind( event, one ); jQuery( this ).unbind( event, one );
return (fn || data).apply( this, arguments ); return fn.apply( this, arguments );
}); });
return this.each(function() { return this.each(function() {
jQuery.event.add( this, type, one, fn && data ); jQuery.event.add( this, type, one, data, thisObject );
}); });
}, },
...@@ -590,10 +611,17 @@ jQuery.fn.extend({ ...@@ -590,10 +611,17 @@ jQuery.fn.extend({
return this; return this;
}, },
live: function( type, data, fn ) { live: function( type, data, fn, thisObject ) {
if ( jQuery.isFunction( data ) ) {
if ( fn !== undefined ) {
thisObject = fn;
}
fn = data;
data = undefined;
}
jQuery( this.context ).bind( liveConvert( type, this.selector ), { jQuery( this.context ).bind( liveConvert( type, this.selector ), {
data: fn && data, selector: this.selector, live: type data: data, selector: this.selector, live: type
}, fn || data ); }, fn, thisObject );
return this; return this;
}, },
...@@ -621,7 +649,7 @@ function liveHandler( event ) { ...@@ -621,7 +649,7 @@ function liveHandler( event ) {
jQuery.each(elems, function() { jQuery.each(elems, function() {
event.currentTarget = this.elem; event.currentTarget = this.elem;
event.data = this.fn.data event.data = this.fn.data;
if ( this.fn.apply( this.elem, args ) === false ) { if ( this.fn.apply( this.elem, args ) === false ) {
return (stop = false); return (stop = false);
} }
...@@ -718,7 +746,7 @@ jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + ...@@ -718,7 +746,7 @@ jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
// Handle event binding // Handle event binding
jQuery.fn[ name ] = function( fn ) { jQuery.fn[ name ] = function( fn ) {
return fn ? this.bind (name, fn ) : this.trigger( name ); return fn ? this.bind( name, fn ) : this.trigger( name );
}; };
}); });
......
...@@ -162,6 +162,25 @@ test("bind(), multi-namespaced events", function() { ...@@ -162,6 +162,25 @@ test("bind(), multi-namespaced events", function() {
jQuery("#firstp").trigger("custom"); jQuery("#firstp").trigger("custom");
}); });
test("bind(), with different this object", function() {
expect(4);
var thisObject = { myThis: true },
data = { myData: true },
handler1 = function( event ) {
equals( this, thisObject, "bind() with different this object" );
},
handler2 = function( event ) {
equals( this, thisObject, "bind() with different this object and data" );
equals( event.data, data, "bind() with different this object and data" );
};
jQuery("#firstp")
.bind("click", handler1, thisObject).click().unbind("click", handler1)
.bind("click", data, handler2, thisObject).click().unbind("click", handler2);
ok( !jQuery.data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different this object and data." );
});
test("unbind(type)", function() { test("unbind(type)", function() {
expect( 0 ); expect( 0 );
...@@ -508,7 +527,7 @@ test("toggle(Function, Function, ...)", function() { ...@@ -508,7 +527,7 @@ test("toggle(Function, Function, ...)", function() {
}); });
test(".live()/.die()", function() { test(".live()/.die()", function() {
expect(54); expect(58);
var submit = 0, div = 0, livea = 0, liveb = 0; var submit = 0, div = 0, livea = 0, liveb = 0;
...@@ -605,6 +624,18 @@ test(".live()/.die()", function() { ...@@ -605,6 +624,18 @@ test(".live()/.die()", function() {
jQuery("#foo").live("click", function(e, data){ equals( data, true, "live with trigger data" ); }); jQuery("#foo").live("click", function(e, data){ equals( data, true, "live with trigger data" ); });
jQuery("#foo").trigger("click", true).die("click"); jQuery("#foo").trigger("click", true).die("click");
// Test binding with different this object
jQuery("#foo").live("click", function(e){ equals( this.foo, "bar", "live with event scope" ); }, { foo: "bar" });
jQuery("#foo").trigger("click").die("click");
// Test binding with different this object, event data, and trigger data
jQuery("#foo").live("click", true, function(e, data){
equals( e.data, true, "live with with different this object, event data, and trigger data" );
equals( this.foo, "bar", "live with with different this object, event data, and trigger data" );
equals( data, true, "live with with different this object, event data, and trigger data")
}, { foo: "bar" });
jQuery("#foo").trigger("click", true).die("click");
// Verify that return false prevents default action // Verify that return false prevents default action
jQuery("#anchor2").live("click", function(){ return false; }); jQuery("#anchor2").live("click", function(){ return false; });
var hash = window.location.hash; var hash = window.location.hash;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment