Как остановить всплытие события в JavaScript — stopPropagation и preventDefault?
У меня клик по кнопке внутри карточки срабатывает и на саму карточку — два обработчика подряд. Как остановить всплытие события, чтобы клик не уходил наверх? И ещё путаю это с отменой действия по умолчанию.
2 ответа
Это два разных метода, их часто путают.
stopPropagation() — останавливает всплытие: событие не пойдёт к родительским элементам. Решает именно твою проблему:
const card = document.querySelector('.card');
const btn = card.querySelector('button');
card.addEventListener('click', () => console.log('клик по карточке'));
btn.addEventListener('click', (e) => {
e.stopPropagation(); // дальше карточке не уйдёт
console.log('клик по кнопке');
});
Теперь клик по кнопке выведет только «клик по кнопке», а не оба сообщения.
preventDefault() — отменяет действие браузера по умолчанию, но всплытие НЕ трогает. Примеры действий по умолчанию: переход по ссылке, отправка формы:
const link = document.querySelector('a');
link.addEventListener('click', (e) => {
e.preventDefault(); // браузер НЕ перейдёт по ссылке
console.log('перехватили клик');
});
Запомни разницу:
stopPropagation— «не передавай событие родителям».preventDefault— «не делай стандартное действие (переход/сабмит)».
Иногда нужны оба сразу — например, у формы: и сабмит отменить, и всплытие остановить. Тогда вызывай обе.
Не злоупотребляй stopPropagation — он может ломать другие обработчики на странице (закрытие модалок, аналитику). Используй точечно.
Полезно понимать сам термин: всплытие (bubbling) — событие сначала срабатывает на самом вложенном элементе, потом «всплывает» вверх по родителям до document. Поэтому клик по кнопке внутри карточки доходит и до карточки.
Иногда вместо stopPropagation достаточно проверить e.target в родителе и игнорировать лишнее — это «мягче» и не глушит событие для всех остальных.