Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Скасування відправки форми». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Щоб форма не відправлялася стандартним способом, треба підписатися на подію `submit` самої форми і викликати в обробнику `event.preventDefault()`.** Після цього браузер не робить власний HTTP-запит на адресу з `action` і не перезавантажує сторінку, а дані можна зібрати через `new FormData(form)` та надіслати вручну через `fetch`. Слухати потрібно саме `submit` на формі, а не `click` на кнопці, бо форма відправляється ще й натисканням Enter у полі. ```javascript const form = document.querySelector('#loginForm'); form.addEventListener('submit', (event) => { event.preventDefault(); }); ``` **Ключове:** `event.preventDefault()` в обробнику `submit` на самій формі, а не в `click` на кнопці.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Стандартна відправка форми скасовується викликом `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` теж працює, але змішує розмітку з логікою і не рекомендується. ### Швидкий приклад ```javascript const form = document.querySelector('#loginForm'); form.addEventListener('submit', (event) => { event.preventDefault(); // скасовуємо стандартну відправку console.log('Форма не перезавантажує сторінку!'); }); ``` ### Стандартна поведінка форми ```html <form id="loginForm" action="/login" method="post"> <input name="username" /> <button type="submit">Увійти</button> </form> ``` За замовчуванням, коли користувач натискає «Увійти»: - браузер збирає всі поля форми; - робить HTTP-запит (зазвичай POST) на `/login`; - і **перезавантажує сторінку**. Саме це перезавантаження й ламає будь-який сценарій із SPA: стан застосунку губиться, а результат запиту неможливо показати без повного рендеру нової сторінки. ### Як скасувати стандартну відправку В обробнику події `submit` викликаємо метод `event.preventDefault()`: ```javascript const form = document.querySelector('#loginForm'); form.addEventListener('submit', (event) => { event.preventDefault(); // скасовуємо стандартну відправку console.log('Форма не перезавантажує сторінку!'); }); ``` Тепер браузер **не перезавантажується**, і ви можете обробити дані самостійно, наприклад через `fetch` або будь-яку HTTP-бібліотеку. ### Приклад з асинхронною обробкою ```html <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 ```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` | > **Запам'ятайте просто:** щоб форма не перезавантажувала сторінку, завжди використовуйте > > ```javascript > form.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`, і губити при цьому чекбокси та поля з однаковими іменами.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.