What it IS:
- You put ONE event listener on a parent element
- When ANY child gets clicked, the event bubbles up to that parent
- The parent handler uses
event.targetto see which specific child was actually clicked - Based on that, you decide what to do
Why it Works:
- Bubbling means child events automatically reach the parent
event.targetnever changes - it always points to the original clicked element- So parent can “see” what child was clicked without having listeners on each child
The Mechanics:
javascript
// Instead of:
child1.onclick = doSomething;
child2.onclick = doSomething;
child3.onclick = doSomething;
// (Repeat for 100 children)
// You do:
parent.onclick = function(e) {
// e.target tells you which child was actually clicked
doSomething(e.target);
};Real Behavior:
- Click child → bubbles to parent → parent asks “who got clicked?” → acts on that specific child
- Add new children? They automatically work (parent catches their bubbles too)
- Remove children? No cleanup needed (no individual listeners to remove)
Main Interview Points:
1. Uses event.target to find what was actually clicked:
javascript
table.onclick = function(event) {
let clicked = event.target; // The actual element clicked
if (clicked.tagName === 'TD') {
highlight(clicked);
}
};
// Works for any number of cells - 10 or 10,0002. Handles dynamic content automatically:
javascript
// Add new buttons later - delegation still works!
container.innerHTML += '<button>New Button</button>';
// No need to attach new event listeners3. Common pattern with data attributes:
javascript
// HTML: <button data-action="save">Save</button>
menu.onclick = function(event) {
let action = event.target.dataset.action; // "save"
if (action) {
this[action](); // Calls this.save()
}
};Interview Gotchas:
Gotcha #1: Click might hit nested elements
javascript
// Problem: <td><strong>Text</strong></td>
// Click on <strong> gives event.target = <strong>, not <td>
// Solution: Use closest()
let td = event.target.closest('td'); // Walks up to find <td>Gotcha #2: Not all events bubble
- Focus/blur events don’t bubble (use focusin/focusout instead)
- Some events like scroll have weird bubbling
Gotcha #3: Performance consideration
javascript
// Handler fires for EVERY click in container
container.onclick = function(event) {
// This runs even for clicks you don't care about
if (event.target.matches('.important')) {
// Only handle important clicks
}
};Bottom Line:
Event delegation = one parent listener catches events from many children. Perfect for dynamic content, saves memory, reduces code. Just remember to check event.target and use closest() for nested elements. It’s the difference between hiring 100 security guards vs. 1 smart one with cameras.
