Це два незалежні механізми, які часто плутають.
preventDefault() скасовує стандартну дію браузера для події:
form.addEventListener('submit', async (event) => {
event.preventDefault(); // не перезавантажувати сторінку
await fetch(form.action, { method: 'POST', body: new FormData(form) });
});
link.addEventListener('click', (event) => {
event.preventDefault(); // не переходити за посиланням
openModal(link.href);
});
Типові стандартні дії: відправка форми, перехід за посиланням, встановлення галочки чекбокса, введення символу в поле при keydown, контекстне меню при правому кліку, прокрутка колесом.
stopPropagation() зупиняє поширення події DOM-деревом: батьківські елементи її не отримають.
dropdown.addEventListener('click', (event) => {
event.stopPropagation(); // клік усередині меню не дійде до document
});
document.addEventListener('click', () => closeAllDropdowns());
Стандартна дія при цьому не скасовується: посилання всередині все одно спрацює.
stopImmediatePropagation() - ще й не викликати інші обробники цього самого елемента, зареєстровані пізніше.
Чому stopPropagation варто уникати:
- він ламає код, що спирається на спливання: делегування подій, аналітику, закриття випадних меню кліком поза ними, обробники фреймворків на
document; - проблему зазвичай краще вирішити перевіркою в батьківському обробнику:
if (dropdown.contains(event.target)) return;.
return false в обробнику, призначеному через onclick="...", скасовує стандартну дію. В addEventListener повернене значення ігнорується - потрібен явний preventDefault().
Пасивні обробники ({ passive: true }) обіцяють браузеру, що preventDefault() не буде викликано. Тоді браузер може почати прокрутку, не чекаючи на обробник. Виклик preventDefault() у пасивному обробнику ігнорується (з попередженням у консолі).
Перевірка: event.defaultPrevented показує, чи хтось уже скасував стандартну дію - корисно, щоб не обробляти подію двічі.
У фреймворках: Alpine @submit.prevent, @click.stop; Livewire wire:submit сам скасовує стандартну відправку форми; Vue - ті самі модифікатори .prevent і .stop.