Describe event delegation and implement a single ul click handler in TypeScript

Event bubbling and parent-level listener efficiency.
Add one listener to the ul, use event.target plus closest to find the li, and type it as MouseEvent.
Attaching listeners to each li or leaving event.target untyped.
WHAT THIS TESTS: This question probes your understanding of the DOM event propagation model, specifically bubbling, and whether you know how to scale event handling without linear growth in listeners. It also checks TypeScript fluency: can you correctly type the event object and safely narrow event.target to the intended element type.
A GOOD ANSWER COVERS: First, a concise explanation of event bubbling: when a user clicks an li, the browser fires a click event on that li and then walks up the ancestor chain, allowing the ul to hear the event. Second, the implementation strategy: select the ul, call addEventListener with a handler typed as (e: MouseEvent) => void, and inside the handler use e.target to locate the originating element. Third, the critical safety step: because e.target could be a nested element inside the li such as a span or icon, use Element.closest('li') to walk upward and find the actual list item; if the click lands on the ul padding outside any li, closest returns null so you guard against that. Fourth, mention the performance and memory win: one listener versus hundreds, which matters on large lists and avoids leaks when items are dynamically added or removed.
COMMON WRONG ANSWERS: A red flag is suggesting document.querySelectorAll('li') and attaching a listener to each node; this defeats the purpose and creates O(n) listener overhead. Another mistake is assuming e.target is always the li and immediately casting it without checking, which breaks when clicks hit nested tags. Some candidates forget TypeScript types entirely and write untyped event parameters or use any, which signals weak type safety habits. A subtle error is using e.currentTarget expecting it to point to the li; currentTarget is the ul where the listener lives, not the clicked child.
LIKELY FOLLOW-UPS: The interviewer may ask how you would handle dynamic items added after the listener is registered, which delegation handles naturally while individual listeners do not. They might ask about event capturing versus bubbling, or how stopPropagation affects delegation. Another follow-up is how to strongly type the li element inside the handler, perhaps using a type guard or generic with closest.
ONE CONCRETE EXAMPLE: In TypeScript, you might write: const list = document.querySelector('ul'); if (!list) return; list.addEventListener('click', (event: MouseEvent) => { const target = event.target as HTMLElement; const li = target.closest('li'); if (!li) return; console.log('Clicked item:', li.textContent); }); This attaches one listener, safely narrows the target, ignores clicks on the ul background, and scales to any number of items.
Source: developer.mozilla.org
Read the original → developer.mozilla.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.