Suggest an editImprove this articleRefine the answer for “Event delegation”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Event delegation is a technique where the handler is attached not to every element but to their common parent, and event bubbling is used to work out which element the action actually happened on.** A single listener manages the events of many child elements: fewer handlers in memory, the logic in one place, and support for elements added dynamically. ```javascript document.body.addEventListener('click', (event) => { if (event.target.matches('button')) { console.log('clicked'); } }); ``` **Key point:** delegation relies on bubbling, and the specific element is identified through `event.target`.Shown above the full answer for quick recall.Answer (EN)Image**Event delegation is a JavaScript technique where we attach the handler not to every element but to their common parent, and use event bubbling to determine which element the action actually happened on.** In other words: a single listener manages the events of many child elements. ## Theory ### TL;DR - One handler on the parent element instead of a hundred handlers on the children. - It works thanks to bubbling: the child's event rises to the parent, which is where it is caught. - The specific element is identified through `event.target`, usually with `matches()` or `closest()`. - It automatically covers elements added to the DOM later. - It does not work for events that do not bubble (`focus`, `blur`, `mouseenter`, `mouseleave`). ### Quick example Say we need to handle clicks on 100 buttons. The naive way, a listener on every button: ```javascript document.querySelectorAll('button').forEach(btn => { btn.addEventListener('click', () => { console.log('clicked'); }); }); ``` The right way, delegation: ```javascript document.body.addEventListener('click', (event) => { if (event.target.matches('button')) { console.log('clicked'); } }); ``` ### Why it is worth doing The key points to name in an interview: - **Fewer handlers,** therefore less memory and a faster page. - **It works for dynamically added elements:** even if an element appeared later, the parent handler still catches it. - **Better manageability:** all the logic lives in one place instead of being smeared across the DOM tree. - **Easier cleanup:** to detach the behaviour you remove one listener instead of walking every node. ### How it works 1. The user clicks a button. 2. The event bubbles up through the DOM tree. 3. The handler on `body` (or on any common ancestor) intercepts the event. 4. We inspect `event.target` to identify the candidate element. A more robust check, for when the button contains nested markup (an icon, a `<span>`): ```javascript list.addEventListener('click', (event) => { const item = event.target.closest('li'); if (!item || !list.contains(item)) return; console.log('Item clicked:', item.dataset.id); }); ``` `closest()` walks up from the actual target until it finds a matching element, so a click on an icon inside the item is handled correctly too. ### target versus currentTarget This is the most common interview slip: - `event.target` is the element that was clicked, that is, the source of the event. - `event.currentTarget` is the element the listener is attached to, that is, the parent. | Property | What it points at | In delegation | | --- | --- | --- | | `event.target` | The real target of the event | The child element we care about | | `event.currentTarget` | The element holding the listener | The parent container | Inside a regular handler function `this` equals `event.currentTarget`, not `target`. ### When delegation is not a fit - **The event does not bubble.** Use `focusin` and `focusout` instead of `focus` and `blur`, and `mouseover` and `mouseout` instead of `mouseenter` and `mouseleave`. - **Someone on the path called `stopPropagation()`.** The event then never reaches the parent listener and delegation silently stops working. - **Very hot events on a large container.** For `mousemove` or `scroll` a single handler on `document` can become the bottleneck; point listeners or throttling are better there. > A short definition, if the interviewer asks for the brief version: event delegation is a technique where one handler on a parent element processes the events of many child elements by relying on event bubbling. ### Common mistakes - **Confusing `target` with `currentTarget`,** and then wondering why the check always yields the parent container. - **Checking only `event.target.matches(...)`** where the target can be a nested node. Use `closest()`. - **Attaching the listener straight to `document` for no reason.** Pick the nearest common ancestor: fewer stray hits and fewer conflicts with other code. - **Forgetting to verify that the found element really sits inside the container.** Without `container.contains(item)` you can match something from an unrelated block. - **Counting on delegation for events that do not bubble,** and then spending a long time on why the handler never fires.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.