What is the exact difference between currentTarget property and target property in JavaScript

Solution 1:

Basically, events bubble by default so the difference between the two is:

  • target is the element that triggered the event (e.g., the user clicked on)
  • currentTarget is the element that the event listener is attached to.

See a simple explanation on this blog post.

Solution 2:

target = element that triggered event.

currentTarget = element that has the event listener.

Solution 3:

Minimal runnable example

window.onload = function() {
  var resultElem = document.getElementById('result')
  document.getElementById('1').addEventListener(
    'click',
    function(event) {
      resultElem.innerHTML += ('<div>target: ' + event.target.id + '</div>')
      resultElem.innerHTML += ('<div>currentTarget: ' + event.currentTarget.id + '</div>')
    },
    false
  )
  document.getElementById('2').dispatchEvent(
          new Event('click', { bubbles:true }))
}
<div id="1">1 click me
  <div id="2">2 click me as well</div>
</div>
<div id="result">
  <div>result:</div>
</div>

If you click on:

2 click me as well

then 1 listens to it, and appends to the result:

target: 2
currentTarget: 1

because in that case:

  • 2 is the element that originated the event
  • 1 is the element that listened to the event

If you click on:

1 click me

instead, the result is:

target: 1
currentTarget: 1

Tested on Chromium 71.

Solution 4:

If this isn't sticking, try this:

current in currentTarget refers to the present. It's the most recent target that caught the event that bubbled up from elsewhere.

Solution 5:

For events whose bubbles is true, they bubble.

Most events do bubble, except several, namely focus, blur, mouseenter, mouseleave, ...

If an event evt bubbles, the evt.currentTarget is changed to the current target in its bubbling path, while the evt.target keeps the same value as the original target which triggered the event.

Event's target types

It is worth noting that if your event handler (of an event that bubbles) is asynchronous and the handler uses evt.currentTarget. currentTarget should be cached locally because the event object is reused in the bubbling chain (codepen).

const clickHandler = evt => {
  const {currentTarget} = evt // cache property locally
  setTimeout(() => {
    console.log('evt.currentTarget changed', evt.currentTarget !== currentTarget)
  }, 3000)
}

If you use React, from v17, react drops the Event Pooling.

Therefore, the event object is refreshed in the handler and can be safe to use in asynchronous calls (codepen).

↑is not always true. onClick event's currentTarget is undefined after the event handler finishes. In conclusion, always cache the event's properties locally if you are going to use them after a synchronous call.

From react docs

Note:

As of v17, e.persist() doesn’t do anything because the SyntheticEvent is no longer pooled.

And many other things that are too long to be pasted in an answer, so I summarized and made a blog post here.