One parent listener
Less setup and simpler cleanup.
Event delegation uses one parent listener to handle events from matching child elements.
list.addEventListener("click", event => {
const button = event.target.closest("[data-remove]");
if (!button) return;
button.closest("li").remove();
});
Events & Forms
Instead of attaching a listener to every child, attach one listener to a stable parent and inspect the event target.
Delegation works because many events bubble from the child to the parent. It is especially useful for lists whose items are added later.
The key pattern is target.closest(selector), followed by a guard when the click did not happen on a matching element.
Less setup and simpler cleanup.
New items work without new listeners.
Find the relevant child control or item.
Ignore events that do not match.
Examples
list.addEventListener("click", event => {
const remove = event.target.closest("[data-remove]");
if (!remove) return;
remove.closest("[data-item]").remove();
});
document.querySelectorAll("[data-remove]").forEach(button => {
button.addEventListener("click", removeItem);
});
// New buttons added later are not covered.
Code patterns
These examples are the event patterns you will reuse constantly: listen, inspect, prevent, delegate, validate and submit.
One listener handles all remove buttons.
list.addEventListener("click", event => {
const button = event.target.closest("[data-remove]");
if (!button) return;
});
Move from button to row.
const item = button.closest("[data-item]");
Guard before changing DOM.
if (!list.contains(button)) return;
Use dataset to choose behavior.
const action = event.target.closest("[data-action]")?.dataset.action;
Rules that matter
Events are user-facing code. Good handlers stay small, respect native behavior and keep visual, semantic and data state aligned.
The parent should exist for the life of the feature.
Clicks often start on nested text or icons.
Not every click inside the parent is relevant.
closest can find ancestors outside a nested context.
data-action can route multiple commands cleanly.
Simple isolated buttons do not need delegation.
Production thinking
Delegation keeps interactive lists fast, simple and reliable when items are created dynamically.
Delegated actions should still use real buttons or links so keyboard users trigger the same events.
Production lists, menus and tables often rely on delegation to avoid thousands of listeners.
Delegated behavior should enhance real markup instead of replacing meaningful links and buttons with generic divs.
Live code lab
The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.
Mini assignment
Practice assignment
Try it yourself
Self-check
If you can explain what fires, where it fires and what default behavior remains, you understand the interaction.