Метод event.preventDefault()
event.preventDefault() скасовує поведінку за замовчуванням, яку браузер виконує для певної події.
Подія все одно відбудеться і всі обробники спрацюють, але браузер не виконає своєї стандартної дії: не перейде за посиланням, не відправить форму, не відкриє контекстне меню.
Теорія
TL;DR
- Метод вимикає вбудовану реакцію браузера на подію, а не саму подію.
- Він не зупиняє поширення: обробники на батьківських елементах усе одно отримають подію, для цього потрібен
stopPropagation(). - Працює лише для подій, у яких узагалі є стандартна дія і які можна скасувати (
event.cancelable === true). - Найчастіші сценарії:
submitформи,clickпо посиланню,contextmenu,dragover, гарячі клавіші. - Після виклику
event.defaultPreventedстаєtrue, і це можна перевірити далі по ланцюжку.
Швидкий приклад
link.addEventListener('click', (event) => {
event.preventDefault(); // переходу не буде
console.log('Посилання клікнуте, але навігації немає');
});Які дії браузера вважаються стандартними
| Елемент / подія | Стандартна поведінка браузера |
|---|---|
<a href="..."> + click | перехід за посиланням |
<form> + submit | відправка форми і перезавантаження сторінки |
<input type="text"> + keypress Enter | може викликати відправку форми |
Контекстне меню (contextmenu) | відкриття меню правою кнопкою миші |
<input type="checkbox"> + click | зміна стану (позначено або знято) |
Приклад 1: скасувати перехід за посиланням
<a href="https://example.com" id="link">Перейти</a>
<script>
const link = document.querySelector('#link');
link.addEventListener('click', (event) => {
event.preventDefault(); // скасовуємо перехід
console.log('Посилання клікнуте, але переходу немає');
});
</script>У консолі з'явиться повідомлення, але сторінка не перейде на інший сайт.
Приклад 2: не дати формі відправитись
<form id="login">
<input type="text" name="login" />
<button>Відправити</button>
</form>
<script>
const form = document.querySelector('#login');
form.addEventListener('submit', (event) => {
event.preventDefault(); // не даємо формі перезавантажити сторінку
console.log('Форму оброблено вручну через JS');
});
</script>Це базовий прийом, коли дані треба відправити через JavaScript (fetch, axios), а не звичайною HTML-відправкою.
Приклад 3: вимкнути контекстне меню
document.addEventListener('contextmenu', (event) => {
event.preventDefault();
console.log('Контекстне меню вимкнено');
});Тепер правий клік не відкриє стандартне меню браузера.
Приклад 4: комбінація зі stopPropagation()
Інколи треба і скасувати дію, і зупинити спливання:
button.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
console.log('Клік перехоплено повністю');
});Обмеження, про які варто пам'ятати
preventDefault()не зупиняє подію: інші обробники, на цьому ж елементі або вище, усе одно виконаються. Щоб обірвати все, потрібенstopImmediatePropagation().- Метод працює лише з подіями, які мають стандартну поведінку. Наприклад, на
clickпо звичайномуdivвін не робить нічого, бо такий клік не викликає жодної стандартної дії. - Якщо
event.cancelable === false(наприклад, подіяscroll), виклик просто ігнорується. - Для пасивних слухачів (
{ passive: true }, а це типова поведінка дляtouchstartіwheelна рівні документа) браузер ігнорує виклик і виводить попередження в консоль. Щоб скасувати прокрутку, слухач треба додати явно з{ passive: false }.
Підсумкова таблиця
| Метод | Що робить | Приклад |
|---|---|---|
event.preventDefault() | Скасовує стандартну поведінку браузера | Не переходити за посиланням, не відправляти форму |
event.stopPropagation() | Припиняє поширення події вгору | Не передавати подію батькам |
event.stopImmediatePropagation() | Повністю зупиняє всі подальші обробники | Обірвати обробку цілком |
Коротка пам'ятка:
preventDefault()це «не роби стандартну дію»,stopPropagation()це «не піднімай подію вгору».
Типові помилки
- Думати, що метод зупиняє подію. Ні, батьківські обробники все одно спрацюють, маршрут події не змінюється.
- Викликати його для події без стандартної дії і чекати ефекту: на
clickпоdivчи на кастомній події це просто нічого не дає. - Викликати після асинхронної операції.
await fetch(...)передpreventDefault()уже пізно: браузер вирішує долю стандартної дії синхронно, одразу після обробника. - Ставити
preventDefault()наsubmit, але забувати про валідацію. Вбудована HTML-валідація відпрацьовує до подіїsubmit, тож ручну перевірку треба писати самому. - Плутати з
return false. У DOM-обробникуreturn falseнічого не скасовує, це поведінка jQuery, де вона означає одразуpreventDefault()іstopPropagation().
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.