659

What is the exact difference between currentTarget and target property in JavaScript events with an example and which property is used in which scenario?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Valli69
  • 8,856
  • 4
  • 23
  • 29
  • Its important esp cause some browsers have different approaches, eg if you listen to a div copy event, in FF you will get a textNode instead of an element, but the listener will be at the div level. – Nikos Apr 04 '16 at 15:21
  • there is a similar concept in as3 language , I have discussed it in both as3 and js and compared them in this post https://stackoverflow.com/a/75975977/6863768 – Amir Rasti Apr 10 '23 at 09:52

10 Answers10

934

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.
Griffin
  • 13,184
  • 4
  • 29
  • 43
  • 233
    target = element that triggered event; currentTarget = element that listens to event. – markmarijnissen Aug 14 '14 at 17:27
  • 4
    @markmarijnissen You should definitely put your comment as an answer since it's more useful than the answer above and more voted also! – Andrea Dec 09 '15 at 17:11
  • Can you please update your answer per [this comment](http://stackoverflow.com/questions/10086427/what-is-the-exact-difference-between-currenttarget-property-and-target-property#comment39457506_10086501) – Rahil Wazir Dec 24 '15 at 12:28
  • 1
    think of currentTarget as "specifiedTarget" – craigmichaelmartin Jul 13 '16 at 15:54
  • It's not always an element. e.g. `XMLHttpRequest` – Knu Jul 28 '18 at 18:33
  • 6
    @markmarijnissen, Elements fires an event, they do not listen to it. We just assign handler to execute it, when it occurs. currentTarget is the one where event handler got attached. – Samyak Jain May 15 '19 at 01:16
  • @markmarijnissen Elements do **not** listen to events. It's the listener (provided by the Web-Api of the browser) that gets attached to the element and listens for events. – m4110c Dec 01 '20 at 14:44
  • here a good explanation with a use case : https://thisthat.dev/current-target-vs-target/ – nitneroc May 11 '22 at 13:52
184

target = element that triggered event.

currentTarget = element that has the event listener.

Martijn
  • 15,791
  • 4
  • 36
  • 68
markmarijnissen
  • 5,569
  • 2
  • 28
  • 34
  • 5
    Elements fire an event, they do not listen to it. We just assign handler to execute it, when it occurs. currentTarget is the one where event handler got attached. – Samyak Jain May 15 '19 at 01:16
  • @SamyakJain Then why is the function called `.addEventListener()` if it doesn't listen to an event? – Samathingamajig Dec 01 '20 at 02:44
  • 5
    @Samathingamajig Because you **add** an event-listener **to** an HTML-element. It's not the element that listens, rather it's a listener in the Web-Api that is provided by the browser. – m4110c Dec 01 '20 at 14:40
70

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.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
37

For events whose bubbles property 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.

Sang
  • 4,049
  • 3
  • 37
  • 47
35

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.

user1164937
  • 1,979
  • 2
  • 21
  • 29
  • 3
    It is useful to look at this from the perspective of the bubbling phase. My initial guess was that `currentTarget` refers to the element that triggered the event, since `current` implies variability and it is the triggered object that can change between events. – Maxim Schmidt Dec 23 '20 at 10:25
14

<style>
  body * {
    margin: 10px;
    border: 1px solid blue;
  }
</style>

<form onclick="alert('form')">FORM
  <div onclick="alert('div')">DIV
    <p onclick="alert('p')">P</p>
  </div>
</form>

If click on the P tag in above code then you will get three alert,and if you click on the div tag you will get two alert and a single alert on clicking the form tag. And now see the following code,

<style>
  body * {
    margin: 10px;
    border: 1px solid blue;
  }
</style>
<script>
function fun(event){
  alert(event.target+" "+event.currentTarget);
}

</script>

<form>FORM
  <div onclick="fun(event)">DIV
    <p>P</p>
  </div>
</form>
We just removed onclick from the P and form tag and now when we click we on P tag we get only one alert:

[object HTMLParagraphElement] [object HTMLDivElement]

Here event.target is [object HTMLParagraphElement],and event.curentTarget is [object HTMLDivElement]: So

event.target is the node from which the event originated, and event.currentTarget, on the opposite, refers to the node on which current-event listener was attached.To know more see bubbling

Here we clicked on P tag but we don't have listener on P but on its parent element div.

Somesh Sharma
  • 529
  • 5
  • 7
10

Event.currentTarget is the element to which the event handler has been attached, as opposed to Event.target, which identifies the element on which the event occurred and which may be its descendant.

Source: MDN

target always refers to the element in front of addEventListener - it's the element on which the event originated. currentTarget tells you - if this is an event that's bubbling - the element that currently has the event listener attached (which will fire the event handler if the event occurs).

See this CodePen for an example. If you open up developer tools and click the square, you'll see that first the div is the target and the currentTarget, but the event bubbles up to the main element - then main element becomes the currentTarget, while the div is still the target. Note the event listener needs to be attached to both elements for the bubbling to occur.

nCardot
  • 5,992
  • 6
  • 47
  • 83
  • I have created test project, it turns out target is same as currentTarget. [codepen](https://codepen.io/javafun/pen/ZEKMqaO) – Vincent Aug 05 '21 at 05:19
  • The event listener needed to be attached to the parent element too for bubbling to work - I tweaked your CodePen to demonstrate this (answer edited) - see https://codepen.io/x-x00102/pen/rNmqwwp – nCardot Aug 06 '21 at 05:36
4

Here's a simple scenario to explain why it's needed. Let's say there are some messages that you show to the user with the format below, but you also want to give them the freedom to close them (unless you have a special mental disorder), so here are some message panes:

[ A message will be in this pane [x] ]

[ A message will be in this pane [x] ]

[ A message will be in this pane [x] ]

and when the user clicks on the [x] button on each, the whole corresponding pane must be removed.

Here's the HTML code for the pane:

<div class="pane">
  A message will be here
  <span class="remove-button">[x]</span>
</div>

Now where do you want to add the click event listener? The user clicks on [x], but you want to remove the pane, so:

  • If you add the click event listener to the [x], then you will have to find its parent on DOM and remove it... which is possible but ugly and "DOM dependent".

  • And if you add the click event listener to the pane, clicking "everywhere on the pane" will remove it, and not just clicking on its [x] button.

So what can we do? We can use the "Bubbles Up" feature of the event system:

"Events are raised and bubble up the DOM tree regardless of the existence of any event handlers."

In our example, this means that even if we add the event handlers to the panes, we will be able to catch the events raised specifically by the [x] button clicks (because events bubble up). So there can be difference between where an event is raised, and where we catch and handle it.

Where it's raised will be in the event.target, and where it's caught will be in the event.currentTarget (where we're currently handling it). So:

let panes = document.getElementsByClassName("pane");
for(let pane of panes){
    pane.addEventListener('click', hndlr);
}
function hndlr(e){
    if(e.target.classList.contains('remove-button')){
        e.currentTarget.remove();
    }
}

(The credit of this example goes to the website JavaScript.info)

aderchox
  • 3,163
  • 2
  • 28
  • 37
3

event.target is the node from which the event originated, ie. wherever you place your event listener (on paragraph or span), event.target refers to node (where user clicked).

event.currentTarget, on the opposite, refers to the node on which current-event listener was attached. Ie. if we attached our event listener on paragraph node, then event.currentTarget refers to paragraph while event.target still refers to span. Note: that if we also have an event listener on body, then for this event-listener, event.currentTarget refers to body (ie. event provided as input to event-listerners is updated each time event is bubbling one node up).

  • 2
    For anyone visiting this page, this answer is incorrect!! Check the accepted answer! This thing should be downvoted into oblivion. delegateTarget is the node which refers to where the event was attached. – LittleTreeX Jun 18 '20 at 20:49
  • @LittleTreeX yeah, it is the indexed answer from google – George Jul 19 '20 at 07:06
-2

An experiment:

document.addEventListener("click", (e) => {
  console.log(e.target, e.currentTarget);
});
document.querySelector("p").click();

output:

<p></p>
#document

The target (<p></p>) seems to be the element clicked, while the currentTarget (#document) is the element that is listening for the click event.

ecraig12345
  • 2,328
  • 1
  • 19
  • 26
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 28 '22 at 13:40