← Все вопросы

Как остановить всплытие события в JavaScript — stopPropagation и preventDefault?

Задан 5 месяцев назад1.3к просмотров2 ответа
8

У меня клик по кнопке внутри карточки срабатывает и на саму карточку — два обработчика подряд. Как остановить всплытие события, чтобы клик не уходил наверх? И ещё путаю это с отменой действия по умолчанию.

2 ответа

12
✓ Принятый ответ — помог автору

Это два разных метода, их часто путают.

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 — он может ломать другие обработчики на странице (закрытие модалок, аналитику). Используй точечно.

4

Полезно понимать сам термин: всплытие (bubbling) — событие сначала срабатывает на самом вложенном элементе, потом «всплывает» вверх по родителям до document. Поэтому клик по кнопке внутри карточки доходит и до карточки.

Иногда вместо stopPropagation достаточно проверить e.target в родителе и игнорировать лишнее — это «мягче» и не глушит событие для всех остальных.

Ваш ответ

Войдите, чтобы ответить на вопрос.