Learn JavaScript

Формы в DOM: input, submit и preventDefault

Форма - стандартный способ собрать данные от пользователя: поиск, вход, подписка, фильтры. В браузере у формы есть встроенное поведение: при отправке (submit) обычно происходит переход или перезагрузка страницы. В JavaScript часто нужно перехватить отправку и обработать данные без перезагрузки.

1) Событие input: реагирование на ввод

input срабатывает каждый раз, когда значение поля меняется.

const search = document.querySelector("input[type='search']");

search.addEventListener("input", (event) => {
  console.log(event.currentTarget.value);
});

event.currentTarget.value - это текущее значение поля.

Полезное отличие от change

change обычно срабатывает позже: когда ввод завершен или поле потеряло фокус.

const search = document.querySelector("input[type='search']");

search.addEventListener("change", (event) => {
  console.log(event.currentTarget.value);
});

2) Событие submit: отправка формы

На отправку формы подписываются на самой форме.

const form = document.querySelector("form");

form.addEventListener("submit", (event) => {
  console.log("submitted");
});

3) preventDefault: отмена перезагрузки

Если не вызвать preventDefault, браузер выполнит стандартное действие (обычно перезагрузка или переход).

const form = document.querySelector("form");

form.addEventListener("submit", (event) => {
  event.preventDefault();
  console.log("handled in JS");
});

Это самый частый шаблон для формы, которая должна обрабатываться через JavaScript.

4) Как прочитать значения полей

Способ 1: querySelector внутри формы

HTML:

<form class="login">
  <input name="email" type="email">
  <input name="password" type="password">
  <button type="submit">Sign in</button>
</form>

JavaScript:

const form = document.querySelector(".login");

form.addEventListener("submit", (event) => {
  event.preventDefault();

  const email = form.querySelector("[name='email']").value;
  const password = form.querySelector("[name='password']").value;

  console.log(email);
  console.log(password);
});

Способ 2: FormData

FormData собирает значения по атрибуту name.

const form = document.querySelector(".login");

form.addEventListener("submit", (event) => {
  event.preventDefault();

  const data = new FormData(form);

  const email = data.get("email");
  const password = data.get("password");

  console.log(email);
  console.log(password);
});

FormData особенно удобен, когда полей много.

5) Какая кнопка отправляет форму

Если у кнопки type="submit", она отправляет форму. Если type не указан, в большинстве случаев кнопка внутри формы тоже считается submit.

HTML:

<form class="search">
  <input name="q" type="search">
  <button>Search</button>
</form>

Чтобы явно сделать кнопку обычной (не отправляющей), ставят type="button":

<button type="button">Open</button>

6) Отправка формы по Enter

Enter в текстовом поле обычно отправляет форму, если есть submit-кнопка. Поэтому даже если клик по кнопке не используется, submit нужен как общий обработчик.

const form = document.querySelector(".search");

form.addEventListener("submit", (event) => {
  event.preventDefault();

  const q = new FormData(form).get("q");
  console.log(q);
});

7) Очистка формы после обработки

Сбросить все поля можно через reset().

const form = document.querySelector(".search");

form.addEventListener("submit", (event) => {
  event.preventDefault();

  const q = new FormData(form).get("q");
  console.log(q);

  form.reset();
});

8) Мини-проверка данных без “сложной логики”

Иногда достаточно проверить, что строка не пустая:

const form = document.querySelector(".search");

form.addEventListener("submit", (event) => {
  event.preventDefault();

  const q = String(new FormData(form).get("q") || "").trim();

  if (q.length === 0) {
    return;
  }

  console.log(q);
});

Частые ошибки

1) Слушатель поставлен на кнопку, а не на форму

Иногда отправка происходит Enter, и обработчик на кнопке не срабатывает. Надежнее слушать submit на форме.

2) Забыть preventDefault

Тогда результат обработки в консоли может мелькнуть и пропасть из-за перезагрузки страницы.

3) Нет атрибута name у input

FormData работает по name. Если name отсутствует, значение не попадет в данные.

Что стоит запомнить

  • input - событие “значение меняется”, удобно для live-поиска и подсказок.
  • submit - событие отправки формы, срабатывает и при клике, и при Enter.
  • preventDefault() останавливает стандартную отправку и перезагрузку.
  • Значения можно читать напрямую из полей или через FormData.
  • Для FormData важен атрибут name.