Event delegation is a JavaScript technique where instead of attaching event listeners to multiple child elements, you attach a single event listener to a parent element and let events “bubble up” from the children.
When an event occurs on a child element, it bubbles up through its ancestors, and the parent’s event listener can detect it. You then check which child triggered the event and handle it accordingly.
Why use event delegation?
✅ Performance – Instead of attaching many listeners to multiple elements, you only attach one to a common ancestor.
✅ Dynamic elements – It works even for elements added to the DOM later (since the listener is on the parent, not the child).
✅ Cleaner code – Fewer event bindings make code easier to maintain.
Example without delegation
// Adding event listeners to each button separately
const buttons = document.querySelectorAll(".btn");
buttons.forEach(button => {
button.addEventListener("click", () => {
console.log("Button clicked:", button.innerText);
});
});
Example with delegation
// Attach one listener to the parent
document.querySelector("#button-container").addEventListener("click", function(e) {
if (e.target.classList.contains("btn")) {
console.log("Button clicked:", e.target.innerText);
}
});
Here:
#button-containeris the parent.- The event listener checks if the actual target (
e.target) has the classbtn. - This way, it works even if new buttons are added dynamically.
👉 In short: Event delegation = listening at a higher level, acting at a lower level.
