1
JavaScriptIntermediate#dom#events
Events travel down (capture) to the target and then bubble up. Delegation exploits bubbling by putting one listener on a parent and inspecting event.target, which is efficient for dynamic lists.
list.addEventListener('click', e => {
const li = e.target.closest('li');
if (li) console.log('clicked', li.dataset.id);
});