Делегирование событий: одна подписка для списка кнопок
Обрабатываем клики динамического списка через общий контейнер и closest, не назначая обработчик каждой кнопке.
- КликСобытие всплывает к контейнеру
- closestИщем нужную кнопку от места клика
- Проверка границыУбеждаемся, что кнопка внутри нашего списка
После обновления списка новые кнопки перестали реагировать на нажатия. Обработчики остались у удалённых элементов, а новая разметка их не получила. Для всплывающих событий можно подписаться один раз на общий контейнер. Найдём нужную кнопку через closest и проверим, что клик пришёл именно из нашего списка.
Находим действие от точки клика
const list = document.querySelector('#tasks');
list.addEventListener('click', event => {
if (!(event.target instanceof Element)) return;
const button = event.target.closest('button[data-task-id]');
if (!button || !list.contains(button)) return;
if (button.disabled) return;
openTask(button.dataset.taskId);
});closest ищет подходящий элемент, начиная с самой цели и двигаясь к предкам. Это важно, когда пользователь нажимает на значок внутри кнопки. Проверка contains ограничивает действие выбранным списком. Функция openTask в примере отвечает за открытие задачи и должна отдельно проверять допустимость идентификатора.
Событие должно доходить до контейнера
Подход опирается на распространение конкретного события. Не все события всплывают одинаково. Для задач фокуса нужно выбирать соответствующее событие или фазу захвата. Чужой stopPropagation также может остановить путь. Перед добавлением ещё одного обработчика посмотрите реальную цепочку в инструментах разработчика.
Используйте настоящие кнопки для действий и ссылки для переходов. Тогда клавиатурная активация и базовая семантика остаются у браузера. Атрибут data-task-id не является проверкой прав: сервер обязан самостоятельно подтвердить доступ к задаче при запросе.
Проверяем обновление списка
Добавьте строку после регистрации обработчика и нажмите и на текст, и на значок кнопки. Проверьте отключённую кнопку и повторное создание компонента: контейнер не должен получить две одинаковые подписки. Когда сам контейнер удаляется, обработчик тоже нужно убрать.
