preventDefault и stopPropagation

event.preventDefault() отменяет стандартное действие браузера для события, а event.stopPropagation() останавливает всплытие события по DOM-дереву вверх.

Зачем нужно

Эти два метода — основной инструмент контроля над поведением событий. Понимание разницы между ними критично: один управляет тем, что делает браузер, другой — тем, кто ещё в DOM получит это событие. Их неверное применение — распространённый источник неочевидных багов.

Где используется

  • Перехват отправки формы для валидации на клиенте (preventDefault)
  • Отключение стандартного перехода по ссылке (preventDefault)
  • Контекстное меню, drag-and-drop (preventDefault)
  • Остановка всплытия при делегировании событий (stopPropagation)
  • Закрытие модального окна по клику на overlay, но не на содержимое (stopPropagation)

preventDefault — отмена действия браузера

// Предотвратить отправку формы
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
  event.preventDefault(); // форма не отправится
  const data = new FormData(form);
  sendData(data); // отправить вручную
});

// Отключить переход по ссылке
document.querySelector('a').addEventListener('click', (event) => {
  event.preventDefault();
  console.log('Клик по ссылке без перехода');
});

// Кастомное контекстное меню
document.addEventListener('contextmenu', (event) => {
  event.preventDefault();
  showCustomMenu(event.clientX, event.clientY);
});

stopPropagation — остановка всплытия

// Модальное окно: клик на overlay закрывает, клик внутри — нет
const modal = document.querySelector('.modal');
const overlay = document.querySelector('.overlay');

overlay.addEventListener('click', () => {
  modal.hidden = true; // закрыть
});

modal.addEventListener('click', (event) => {
  event.stopPropagation(); // не дать событию дойти до overlay
});
// Логирование без мешания другим обработчикам
document.addEventListener('click', (event) => {
  // НЕ останавливаем здесь — просто логируем
  console.log('Клик на:', event.target);
});

button.addEventListener('click', (event) => {
  event.stopPropagation(); // другие обработчики выше не получат событие
  handleButtonClick;
});

stopImmediatePropagation

// Останавливает и всплытие, и другие обработчики на том же элементе
btn.addEventListener('click', (event) => {
  event.stopImmediatePropagation();
  console.log('Первый обработчик');
});

btn.addEventListener('click', () => {
  // Этот обработчик НЕ выполнится
  console.log('Второй обработчик');
});

Разница между методами

Метод Что делает Что НЕ делает
preventDefault Отменяет браузерное действие Не останавливает всплытие
stopPropagation Останавливает всплытие Не отменяет браузерное действие
stopImmediatePropagation Останавливает всплытие + другие обработчики элемента

Частые ошибки

  • return false в addEventListener — в отличие от inline-обработчиков или jQuery, return false в addEventListener не вызывает preventDefault/stopPropagation.
  • Злоупотребление stopPropagation — останавливает события для других слушателей выше по дереву (аналитика, общие обработчики), что может приводить к трудноуловимым багам; используйте с умом.
  • Вызов preventDefault на не-отменяемом событии — проверяйте event.cancelable перед вызовом, если есть сомнения.

Связанные темы

Ресурсы