Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix #10563. Ensure event.currentTarget==this if delegated.
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.