1. Delegated list clicks

One listener for many buttons.

List

Click an item

Clicks report id below.

list.addEventListener('click', (e) => {
  const btn = e.target.closest('button[data-id]');
  if (!btn) return;
  console.log(btn.dataset.id);
});

2. Remove row delegation

Delete buttons work on new rows too.

Table
A

Add row then remove with ×.

tbody.addEventListener('click', (e) => {
  if (e.target.matches('.remove-row')) {
    e.target.closest('tr').remove();
  }
});

3. passive scroll listeners

Mark scroll/touch listeners passive when not preventDefault.

Note

Use { passive: true } for scroll performance unless blocking scroll.

Improves main-thread scrolling.

window.addEventListener('scroll', onScroll, { passive: true });

Frequently asked questions

Delegation vs many listeners?
Delegation scales for dynamic lists; direct listeners are fine for few static nodes.
Mouseenter delegation?
mouseenter does not bubble. Use mouseover or pointer events.
React virtual DOM?
Frameworks re-bind differently; delegation pattern still applies at root.