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перед вызовом, если есть сомнения.