Events and Event HandlingLesson 2.3
Event delegation: handling clicks on dynamic elements
event delegation pattern, e.target, matches method, dynamic children, performance benefits
Event Delegation
Event delegation attaches a single listener to a parent element instead of one listener per child. Because events bubble, the parent catches all child events.
This is critical for dynamically added elements โ listeners attached before an element existed do not work on that element.
const list = document.querySelector('#task-list');
list.addEventListener('click', (e) => {
// e.target is the exact element clicked
if (e.target.matches('.delete-btn')) {
e.target.closest('li').remove();
}
if (e.target.matches('.complete-btn')) {
e.target.closest('li').classList.toggle('done');
}
});Why Not One Listener Per Child?
Attaching 500 listeners for a 500-item list wastes memory and slows down the page. One delegated listener scales to any number of children at no extra cost.
The matches() Method
element.matches(selector) returns true if the element matches the CSS selector. It is the idiomatic way to filter which child triggered the parent listener.
if (e.target.matches('button[data-action="delete"]')) {
handleDelete(e.target.dataset.id);
}