Скасування відправки форми
Стандартна відправка форми скасовується викликом event.preventDefault() в обробнику події submit. Після цього браузер не робить власний запит на action і не перезавантажує сторінку, тож розробник обробляє дані сам, зазвичай через fetch.
Теорія
TL;DR
- За замовчуванням
submitзбирає поля, робить HTTP-запит наactionі перезавантажує сторінку. event.preventDefault()в обробникуsubmitскасовує цю стандартну поведінку.- Дані форми зручно діставати через
new FormData(form)іObject.fromEntries(formData.entries()). - Далі запит відправляється вручну:
fetch()або будь-який HTTP-клієнт. - Слухати треба
submitна формі, а неclickна кнопці: форма відправляється і по Enter у полі. - Інлайновий атрибут
onsubmitтеж працює, але змішує розмітку з логікою і не рекомендується.
Швидкий приклад
const form = document.querySelector('#loginForm');
form.addEventListener('submit', (event) => {
event.preventDefault(); // скасовуємо стандартну відправку
console.log('Форма не перезавантажує сторінку!');
});Стандартна поведінка форми
<form id="loginForm" action="/login" method="post">
<input name="username" />
<button type="submit">Увійти</button>
</form>За замовчуванням, коли користувач натискає «Увійти»:
- браузер збирає всі поля форми;
- робить HTTP-запит (зазвичай POST) на
/login; - і перезавантажує сторінку.
Саме це перезавантаження й ламає будь-який сценарій із SPA: стан застосунку губиться, а результат запиту неможливо показати без повного рендеру нової сторінки.
Як скасувати стандартну відправку
В обробнику події submit викликаємо метод event.preventDefault():
const form = document.querySelector('#loginForm');
form.addEventListener('submit', (event) => {
event.preventDefault(); // скасовуємо стандартну відправку
console.log('Форма не перезавантажує сторінку!');
});Тепер браузер не перезавантажується, і ви можете обробити дані самостійно, наприклад через fetch або будь-яку HTTP-бібліотеку.
Приклад з асинхронною обробкою
<form id="form">
<input name="email" type="email" placeholder="Email" required />
<input name="password" type="password" placeholder="Пароль" required />
<button>Увійти</button>
</form>
<script>
const form = document.querySelector('#form');
form.addEventListener('submit', async (e) => {
e.preventDefault(); // скасовуємо стандартну поведінку
const formData = new FormData(form);
const data = Object.fromEntries(formData.entries());
console.log('Надсилаємо через JS:', data);
const res = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
const result = await res.json();
console.log('Відповідь сервера:', result);
});
</script>Що тут відбувається:
- форма не перезавантажується;
- дані беруться з полів через
FormData; - запит іде асинхронно через
fetch; - результат можна показати прямо на сторінці.
Альтернатива: атрибут onsubmit в HTML
<form onsubmit="event.preventDefault(); alert('Не перезавантажується!')">
<input placeholder="Ім'я" />
<button>Відправити</button>
</form>Такий варіант працює, але не рекомендується: суміш JS і HTML ускладнює підтримку коду, заважає перевикористанню обробника і погано дружить з Content Security Policy.
Підсумкова таблиця
| Що потрібно зробити | Як правильно |
|---|---|
| Скасувати перезавантаження сторінки | event.preventDefault() в обробнику submit |
| Отримати дані форми | new FormData(form) |
| Відправити дані вручну | fetch() або HTTP-клієнт на ваш вибір |
| Надійний спосіб | Слухати submit, а не click |
Запам'ятайте просто: щоб форма не перезавантажувала сторінку, завжди використовуйте
javascriptform.addEventListener('submit', (e) => e.preventDefault());
Типові помилки
- Скасовувати відправку в обробнику
clickна кнопці:button.addEventListener('click', (e) => e.preventDefault()). Це не гарантує, що форма не відправиться, бо натискання Enter у полі теж викликаєsubmit. - Забувати
event.preventDefault()і дивуватися, чому сторінка «мигає» і стан застосунку скидається. - Ставити обробник до того, як форма з'явилася в DOM:
document.querySelector('#form')повернеnull, іaddEventListenerвпаде з помилкою. - Використовувати
return falseу слухачі, доданому черезaddEventListener. Там воно не працює, на відміну від старих інлайнових обробників. - Викликати
preventDefault()післяawait: до цього моменту подія вже оброблена браузером, тож скасування треба робити першою дією обробника. - Забирати дані вручну через
document.querySelectorдля кожного поля замістьFormData, і губити при цьому чекбокси та поля з однаковими іменами.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.