Как называется подход, когда обработчик клика вешается на контейнер, а событие обрабатывается на дочерних элементах
Что проверяют
Знаете ли вы термин «делегирование событий» и, главное, на чём он держится: на всплытии. Следом обычно дают вёрстку, где внутри пункта списка лежит иконка или <span>, и просят написать обработчик, который не сломается от клика по ним.
Как отвечать
Название: делегирование событий, event delegation. Работает оно потому, что событие проходит три фазы: погружение от window к элементу, фазу цели и всплытие обратно вверх. Обработчик на контейнере получает клики по всем потомкам и по event.target понимает, где именно кликнули.
list.addEventListener('click', (event) => {
const item = event.target.closest('.item');
if (!item || !list.contains(item)) return;
select(item.dataset.id);
});closest, а неmatches:event.targetэто самый глубокий элемент под курсором, например<span>внутри пункта. Проверкаevent.target.matches('.item')на нём промахнётся;contains: страхует от совпадения с элементом выше контейнера, если списки вложены друг в друга;event.currentTarget: сам контейнер, на котором висит обработчик, в отличие отtarget.
Зачем это нужно: один обработчик вместо сотни, и элементы, добавленные позже, работают без повторной подписки. Типичные места: списки, таблицы, меню, бесконечная лента.
Про React скажите отдельно: он делегирует события сам, начиная с версии 17 на корневой контейнер приложения, а не на document. Поэтому вручную делегировать в React обычно незачем.
Где спотыкаются
Проверяют event.target напрямую и получают обработчик, который срабатывает при клике по пустому месту пункта, а по тексту внутри <span> молчит.
Не знают, какие события не всплывают. focus, blur, mouseenter и mouseleave так делегировать не выйдет, вместо них берут focusin, focusout, mouseover и mouseout.
Забывают про stopPropagation во вложенных обработчиках. Любой потомок, остановивший всплытие, молча выключает делегированный обработчик для своей области.