event.target and event.currentTarget

`event.target` identifies the event's target, while `event.currentTarget` identifies the object whose listener is currently running. The distinction is essential for event delegation and understanding propagation, especially when nested elements or Shadow DOM are involved.

`event.target` is the event's target: the object associated with the event at its origin. For a user click, this is often the element the user activated. In a delegated listener on a container, it can be a nested descendant rather than the container itself.

`event.currentTarget` is the object whose listener is currently being invoked. If a click bubbles from a button to its parent, the button listener sees the button as `currentTarget`, and the parent listener sees the parent. The `target` remains the button in both listeners, unless event retargeting applies.

These properties work with both capture- and bubble-phase listeners. `currentTarget` is meaningful while a listener is executing; outside that invocation, it is generally `null`. If code needs to use it asynchronously, save the value inside the listener rather than assuming it will still be set later.

Shadow DOM can retarget events as they cross a shadow boundary, so `target` observed outside a component may be the host rather than the internal node. For composed events, `composedPath()` can expose the propagation path subject to the platform's visibility rules.

Key points

Interview questions

What is the difference between `event.target` and `event.currentTarget`?

`target` is the event target, commonly the element where a click originated. `currentTarget` is the node whose registered listener is running. As a bubbling event reaches ancestor listeners, `currentTarget` changes while `target` usually remains the same, except where retargeting changes the visible target.

How do `target` and `currentTarget` help implement event delegation?

A listener attached to a list container can handle clicks from its descendants because bubbling delivers those events to the container. Use `event.target` to identify the originating descendant, but verify it is the desired kind of element, for example with `closest()` and a containment check. Use `event.currentTarget` to refer to the container that owns the delegated listener. This avoids installing a separate listener on every child.

What should you consider when reading `currentTarget` in asynchronous event-handler code?

An event listener's `currentTarget` is associated with the current listener invocation, not a durable reference to the listener node. After dispatch completes, the property is generally `null`, so reading it after an `await` can produce a different result from reading it synchronously. Capture the needed node before yielding, such as `const root = event.currentTarget`. Also note that the `target` may be retargeted at a Shadow DOM boundary.

Do `target` and `currentTarget` behave differently in capture and bubble listeners?

During capture, listeners run along the path toward the target; during bubbling, eligible ancestor listeners run on the way back. In either phase, `currentTarget` identifies the node whose listener is running at that moment. `target` identifies the event's target as exposed to that listener, and Shadow DOM retargeting can affect what it exposes. `eventPhase` tells you the dispatch phase rather than the target node.