event.target vs currentTarget in JavaScript
Learn the key difference between event.target and event.currentTarget in JavaScript. Understand which refers to the clicked element and which refers to the listener's element.
event.target and event.currentTarget are two properties on every event object. They both refer to DOM elements, but they answer different questions:
event.target: which element did the user actually interact with?event.currentTarget: which element is the event listener attached to?
Here is the simplest demonstration: a button nested inside a div, with the listener attached to the outer element:
<div id="parent">
<button id="child">Click me</button>
</div>Clicking the button fires the listener on the parent because the click bubbles up to it. Logging both properties inside the handler shows how they differ:
const parent = document.querySelector("#parent");
parent.addEventListener("click", (event) => {
console.log("target:", event.target.id); // "child"
console.log("currentTarget:", event.currentTarget.id); // "parent"
});The listener is on the <div> but the user clicked the <button> inside it, so the two properties point to different elements: one to the button, the other to the div. They differ because the event bubbled up from the button to the div.
The Rule in One Sentence
event.target is the element that triggered the event. event.currentTarget is the element that is handling the event.
When the listener is directly on the element that was clicked, both properties refer to the same element:
button.addEventListener("click", (event) => {
console.log(event.target === event.currentTarget); // true
console.log(event.target === button); // true
});When the listener sits on an ancestor and the click happened on a nested child instead, the two properties point to different elements and the comparison returns false:
parent.addEventListener("click", (event) => {
console.log(event.target === event.currentTarget); // false
// target: the child button
// currentTarget: the parent div
});Comparison Table
event.target | event.currentTarget | |
|---|---|---|
| What it points to | The deepest element the user interacted with | The element the listener is attached to |
| Changes during propagation? | No | Yes, it is always the current element in the propagation path |
| Used for | Identifying which child was clicked | Referencing the listening element in reusable handlers |
| In event delegation | The child that triggered the event | The parent with the listener |
| Outside a handler | Still the original target | null |
Why the Distinction Matters for Event Delegation
Event delegation is the most common reason you need to understand this difference. You attach one listener to a parent and use event.target to identify which child was interacted with:
const list = document.querySelector("ul");
list.addEventListener("click", (event) => {
if (event.target.matches("li")) {
console.log(`You clicked: ${event.target.textContent}`);
}
console.log(`Listener is on: ${event.currentTarget.tagName}`); // "UL"
});The listener's element is always the <ul> because that is where it lives, while the deepest element is whichever <li> the user clicked. Without this distinction, event delegation would not be possible.
For a deeper explanation of delegation, see /javascript/javascript-event-delegation-complete-tutorial. For the broader context of how events travel through the DOM, see /javascript/javascript-event-bubbling-and-capturing-guide.
target vs currentTarget in Nested Elements
When clickable elements contain other elements (icons, spans, images), event.target can be surprising:
<button id="save-btn">
<span class="icon">💾</span>
Save
</button>The button contains an icon, so a click on that icon still needs to activate the button's own listener. Logging both properties shows how each one handles that nested click differently:
document.querySelector("#save-btn").addEventListener("click", (event) => {
console.log(event.target); // The <span> if user clicked the icon
console.log(event.currentTarget); // Always the <button>
});If the user clicks the floppy disk icon, event.target is the <span>, not the <button>. This is often unexpected. The fix is event.currentTarget when you need the button, or event.target.closest("button") when you need to walk up from whatever was clicked:
document.querySelector("#save-btn").addEventListener("click", (event) => {
const button = event.currentTarget; // Always the button, regardless of click position
console.log("Save clicked:", button.id);
});Using currentTarget with a Reusable Named Function
When the same function handles events on multiple elements, event.currentTarget tells you which one:
function handleButtonClick(event) {
console.log(`Clicked button with text: ${event.currentTarget.textContent}`);
}
document.querySelector("#save").addEventListener("click", handleButtonClick);
document.querySelector("#delete").addEventListener("click", handleButtonClick);
document.querySelector("#edit").addEventListener("click", handleButtonClick);The same handleButtonClick function works for all three buttons because it always reads the listener's own element rather than whatever was clicked inside it. Reading the deepest clicked element here would give the wrong result whenever a button contains an icon.
When event.target and event.currentTarget Are the Same
They are identical when the listener is directly on the element the user interacts with and there are no child elements involved:
const button = document.querySelector("button");
button.addEventListener("click", (event) => {
console.log(event.target === event.currentTarget); // true
console.log(event.target === button); // true
});This holds as long as the button contains no child elements (text content is not a child element). As soon as you add a <span> or icon inside the button, event.target may point to the child instead.
Common Mistakes
Reading the wrong property by accident. If your handler is on a button and you read event.target.textContent, a click on an icon inside the button may return the icon's empty text content. Read from the listener's own element instead when that is what you actually need.
Storing event.currentTarget for later use. event.currentTarget is null outside the active handler. If you save the event object and access currentTarget in a setTimeout or after an await, it will be null:
button.addEventListener("click", (event) => {
const target = event.currentTarget; // Save it now
setTimeout(() => {
console.log(event.currentTarget); // null
console.log(target); // Still the button
}, 1000);
});Expecting the parent when a child is clicked. Clicks on children bubble up, and this property is always the deepest element in the DOM tree at the click coordinates. Use closest() if you need to find the nearest matching ancestor instead.
Rune AI
Key Insights
- event.target is the element the user interacted with (the deepest element).
- event.currentTarget is the element the listener is attached to.
- In event delegation, target identifies the child and currentTarget identifies the parent.
- currentTarget equals this in regular functions but not in arrow functions.
- event.currentTarget is null outside the active event handler.
Frequently Asked Questions
Is event.currentTarget always the same as this inside a listener?
What is currentTarget when the event is not inside a handler?
Which one should I use for event delegation?
Conclusion
event.target tells you which element the user actually interacted with, even if that element is deep inside the element with the listener. event.currentTarget tells you which element the listener is attached to. The distinction is essential for event delegation, click-outside detection, and any time user interaction can originate from a child element.
More in this topic
Using Decorators for Logging in JS Architecture
Learn how JavaScript decorators wrap class methods to add logging without touching the original code, including setup with Babel and how execution order works.
JavaScript While Loop Explained: A Complete Guide
A while loop repeats code as long as a condition stays true. Learn the syntax, see practical examples, and understand when a while loop is the right choice over a for loop.
JavaScript Loops Tutorial: for, while, do while
Loops let JavaScript repeat code without writing it twice. Learn the three core loop types, what each one does, and when to choose one over another.