Why does e.currentTarget change with jQuery event delegation?

http://jsbin.com/xaguxuhiwu/1/edit?html,js,console,output

  <div id="container">
    <button id="foo">Foo button</button>
    <button id="bar">Bar button</button>
  </div>

$('#container').on('click', function(e) {
  var targetId = e.target.getAttribute('id');
  // Manually do event delegation
  if (targetId === 'foo') {
    var currentId = e.currentTarget.getAttribute('id');
    console.log('without delegation, currentTarget is: ' + currentId);
  }
});

$('#container').on('click', '#foo', function(e) {
    var currentId = e.currentTarget.getAttribute('id');
    console.log('with delegation, currentTarget is: ' + currentId);
});

      

Basically, my understanding of e.currentTarget for an event is that it reflects the point to which the event happened. Since I have an event listener on an element #container

, I would expect currentTarget to be container

in both scenarios.

This is true for the standard handler on

, as shown in the first example. However, when using Delegation Delegation (argument #foo

on second click), currentTarget is changed to an internal button.

Why does it change e.currentTarget

between the two scenarios? Specifically, in the latter case, does this mean that jQuery does not put an event listener on the parent ( #container

) element ?

+3


source to share


2 answers


This is mainly due to the jQuery magic behind the scenes. The jQuery event object that wraps its own event is modified currentTarget

to be more convenient.

In order to access the value usually denoted currentTarget

, jQuery events have delegateTarget

.

This property is most often useful in delegated events, attached .delegate()

or .on()

where an event handler is bound to an ancestor of the element being processed. It can be used, for example, to identify and remove event handlers at a delegation point.

For non-delegated event handlers attached directly to the element, event.delegateTarget

will always be event.currentTarget

.



You can see that in originalEvent

, currentTarget

has the value that you expect.

$('#container').on('click', function(e) {
    console.log('without delegation:');
    console.log('target: ' + e.target.getAttribute('id'));
    console.log('currentTarget: ' + e.currentTarget.getAttribute('id'));
    console.log('originalEvent.currentTarget: ' + e.originalEvent.currentTarget.getAttribute('id'));
    console.log('delegateTarget: ' + e.delegateTarget.getAttribute('id'));
    console.log('--');
});
$('#container').on('click', '#foo', function(e) {
    console.log('with delegation:');
    console.log('target: ' + e.target.getAttribute('id'));
    console.log('currentTarget: ' + e.currentTarget.getAttribute('id'));
    console.log('originalEvent.currentTarget: ' + e.originalEvent.currentTarget.getAttribute('id'));
    console.log('delegateTarget: ' + e.delegateTarget.getAttribute('id'));
    console.log('--');
});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
    <button id="foo">Foo button</button>
    <button id="bar">Bar button</button>
</div>
      

Run codeHide result


+5


source


In simple terms, "#foo" is the current DOM element since you clicked it. It's just a DOM element, parent (or parent parent, etc.) turns out to be "#container".

So the answer to your question is "The current DOM element is in the bubble phase ." [as per jQuery docs) - "#foo".



Likewise, if you called $(document).on("click","#foo",...

, your currentTarget will also be "#foo".

0


source







All Articles