Skip to content

Commit

Permalink
Fix #10563. Ensure event.currentTarget==this if delegated.
Browse files Browse the repository at this point in the history
Now, event.delegateTarget is always the element where the event was handled, regardless of whether delegated handlers are attached.
  • Loading branch information
dmethvin committed Oct 24, 2011
1 parent 560c33b commit 84d2307
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 22 deletions.
10 changes: 5 additions & 5 deletions src/event.js
Expand Up @@ -412,7 +412,7 @@ jQuery.event = {

// Use the fix-ed jQuery.Event rather than the (read-only) native event
args[0] = event;
event.currentTarget = this;
event.delegateTarget = this;

// Determine handlers that should run if there are delegated events
// Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861)
Expand Down Expand Up @@ -447,18 +447,18 @@ jQuery.event = {
handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
}

// Run delegates first; they may want to stop propagation beneath us
for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
matched = handlerQueue[ i ];
event.currentTarget = matched.elem;

for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
handleObj = matched.matches[ j ];

// Triggered event must either 1) be non-exclusive and have no namespace, or
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {

// Pass in a reference to the handler function itself
// So that we can later remove it
event.handler = handleObj.handler;
event.data = handleObj.data;
event.handleObj = handleObj;

Expand Down Expand Up @@ -929,7 +929,7 @@ jQuery.fn.extend({
if ( types && types.preventDefault && types.handleObj ) {
// ( event ) dispatched jQuery.Event
var handleObj = types.handleObj;
jQuery( types.currentTarget ).off(
jQuery( types.delegateTarget ).off(
handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type,
handleObj.selector,
handleObj.handler
Expand Down
38 changes: 21 additions & 17 deletions test/unit/event.js
Expand Up @@ -1060,7 +1060,7 @@ test("trigger(eventObject, [data], [fn])", function() {
// Tries bubbling
equals( e.type, "foo", "Verify event type when passed passing an event object" );
equals( e.target.id, "child", "Verify event.target when passed passing an event object" );
equals( e.currentTarget.id, "par", "Verify event.target when passed passing an event object" );
equals( e.currentTarget.id, "par", "Verify event.currentTarget when passed passing an event object" );
equals( e.secret, "boo!", "Verify event object's custom attribute when passed passing an event object" );
});

Expand Down Expand Up @@ -1160,18 +1160,20 @@ test("jQuery.Event( type, props )", function() {
});

test("jQuery.Event.currentTarget", function(){
expect(1);

var counter = 0,
$elem = jQuery("<button>a</button>").click(function(e){
equals( e.currentTarget, this, "Check currentTarget on "+(counter++?"native":"fake") +" event" );
});

// Fake event
$elem.trigger("click");

// Cleanup
$elem.unbind();
expect(2);

jQuery('<div><p><button>shiny</button></p></div>')
.on( "click", "p", function( e ){
equals( e.currentTarget, this, "Check delegated currentTarget on event" );
})
.find( "button" )
.on( "click", function( e ){
equals( e.currentTarget, this, "Check currentTarget on event" );
})
.click()
.off( "click" )
.end()
.off( "click" );
});

test("toggle(Function, Function, ...)", function() {
Expand Down Expand Up @@ -1253,7 +1255,7 @@ test("toggle(Function, Function, ...)", function() {
});

test(".live()/.die()", function() {
expect(65);
expect(66);

var submit = 0, div = 0, livea = 0, liveb = 0;

Expand Down Expand Up @@ -1476,7 +1478,8 @@ test(".live()/.die()", function() {
// Test this, target and currentTarget are correct
jQuery("span#liveSpan1").live("click", function(e){
equals( this.id, "liveSpan1", "Check the this within a live handler" );
equals( e.currentTarget, document, "Check the event.currentTarget within a live handler" );
equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a live handler" );
equals( e.delegateTarget, document, "Check the event.delegateTarget within a live handler" );
equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a live handler" );
});

Expand Down Expand Up @@ -1784,7 +1787,7 @@ test("live with special events", function() {
});

test(".delegate()/.undelegate()", function() {
expect(64);
expect(65);

var submit = 0, div = 0, livea = 0, liveb = 0;

Expand Down Expand Up @@ -2008,7 +2011,8 @@ test(".delegate()/.undelegate()", function() {
// Test this, target and currentTarget are correct
jQuery("#body").delegate("span#liveSpan1", "click", function(e){
equals( this.id, "liveSpan1", "Check the this within a delegate handler" );
equals( e.currentTarget, document.body, "Check the event.currentTarget within a delegate handler" );
equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a delegate handler" );
equals( e.delegateTarget, document.body, "Check the event.delegateTarget within a delegate handler" );
equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a delegate handler" );
});

Expand Down

1 comment on commit 84d2307

@SlexAxton
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think something might be weird with this commit. I've reopened the ticket for investigation: http://bugs.jquery.com/ticket/10563#comment:6

Please sign in to comment.