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 = {
return event;
},
proxy: function( fn, proxy ) {
proxy = proxy || function() { return fn.apply( this, arguments ); };
proxy: function( fn, proxy, thisObject ) {
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
proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
// So proxy can be declared as an argument
......@@ -509,19 +514,35 @@ jQuery.each({
});
jQuery.fn.extend({
bind: function( type, data, fn ) {
return type === "unload" ? this.one(type, data, fn) : this.each(function() {
jQuery.event.add( this, type, fn || data, fn && data );
bind: function( type, data, fn, thisObject ) {
if ( jQuery.isFunction( 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 ) {
var one = jQuery.event.proxy( fn || data, function( event ) {
one: function( type, data, fn, thisObject ) {
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 );
return (fn || data).apply( this, arguments );
return fn.apply( this, arguments );
});
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({
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 ), {
data: fn && data, selector: this.selector, live: type
}, fn || data );
data: data, selector: this.selector, live: type
}, fn, thisObject );
return this;
},
......@@ -621,7 +649,7 @@ function liveHandler( event ) {
jQuery.each(elems, function() {
event.currentTarget = this.elem;
event.data = this.fn.data
event.data = this.fn.data;
if ( this.fn.apply( this.elem, args ) === false ) {
return (stop = false);
}
......@@ -718,7 +746,7 @@ jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
// Handle event binding
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() {
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() {
expect( 0 );
......@@ -508,7 +527,7 @@ test("toggle(Function, Function, ...)", function() {
});
test(".live()/.die()", function() {
expect(54);
expect(58);
var submit = 0, div = 0, livea = 0, liveb = 0;
......@@ -605,6 +624,18 @@ test(".live()/.die()", function() {
jQuery("#foo").live("click", function(e, data){ equals( data, true, "live with trigger data" ); });
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
jQuery("#anchor2").live("click", function(){ return false; });
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