W3docs

JavaScript Form submit() и события форм

Как работают событие submit, form.submit() и form.requestSubmit() в JavaScript: валидация, preventDefault(), кнопка submitter и чтение данных формы.

Обработка отправки форм — одна из наиболее распространённых задач во фронтенд-JavaScript. Формы — это способ, которым пользователи передают данные на сервер: вход в систему, регистрация, поиск, оформление заказа. Почти всегда нужна возможность проверить, преобразовать или подтвердить эти данные до того, как они покинут страницу.

Для этого существуют два связанных, но различных инструмента:

  • Событие submit — генерируется браузером, когда пользователь пытается отправить форму (нажимая кнопку отправки или клавишу Enter в поле ввода). Здесь выполняется валидация и принимается решение — разрешить или отменить отправку.
  • Метод form.submit() — отправляет форму программно из кода, без каких-либо действий пользователя.

Важный нюанс, который часто сбивает с толку разработчиков: эти два инструмента несимметричны. Вызов form.submit() не генерирует событие submit и полностью пропускает проверку ограничений. Ниже рассмотрим причины этого и чем лучше воспользоваться вместо него.

Понимание события submit

Событие submit генерируется, когда форма собирается отправить данные. Важно, что оно можно отменить: вызов event.preventDefault() внутри обработчика останавливает переход браузера на другую страницу — это позволяет оставить пользователя на текущей странице для проверки ввода, отображения ошибок или отправки данных через fetch.

Событие генерируется когда:

  • Пользователь нажимает <button type="submit"> или <input type="submit"> внутри формы.
  • Пользователь нажимает Enter, находясь в текстовом поле формы, у которой есть кнопка отправки.

Оно не генерируется при вызове form.submit() из JavaScript (см. ниже).

Пример: валидация формы перед отправкой

Этот скрипт предотвращает отправку формы, если поля заполнены некорректно, и показывает пользователю сообщение об ошибке. Он использует встроенную браузерную проверку ограничений (атрибут required и type="email") через checkValidity().

<div>
  <form style="display: flex; justify-content: center; gap: 2px; align-items: center; flex-direction: column;" id="registrationForm">
    Username: <input type="text" name="username" required />
    Email: <input type="email" name="email" required />
    <button type="submit">Register</button>
  </form>
  <div id="message" style="margin-top: 10px; text-align:center;"></div> <!-- Message container for feedback -->
  <script>
    const form = document.getElementById('registrationForm');
    form.addEventListener('submit', function(event) {
      event.preventDefault(); // Prevent actual form submission to a server
      const messageDiv = document.getElementById('message');
      if (!this.checkValidity()) {
        messageDiv.textContent = 'Please fill all required fields correctly.';
        messageDiv.style.color = 'red'; // Display the message in red for errors
      } else {
        messageDiv.textContent = 'The form was successfully submitted.';
        messageDiv.style.color = 'green'; // Display the message in green for success
        form.reset(); // Reset the form fields after successful submission
      }
    });
  </script>
</div>

Функциональность JavaScript:

  • Обработчик события: к форме прикреплён обработчик события, который срабатывает при попытке её отправки.
  • Проверка валидации: здесь используется функция checkValidity(). Это встроенный метод HTML-формы, который проверяет все поля на соответствие правилам валидации (например, атрибут required в данном случае). Если хотя бы одно поле не соответствует правилу, функция возвращает false.
  • Предотвращение отправки: если checkValidity() возвращает false (то есть форма содержит невалидные или незаполненные обязательные поля), скрипт предотвращает отправку формы на сервер. Вместо этого отображается сообщение с просьбой правильно заполнить все обязательные поля.
  • Обработка отправки: если все поля валидны, форма показывает сообщение об успехе вместо пустой страницы или отправки на сервер. В реальном приложении именно здесь вы бы вызывали fetch() для отправки данных.

Чтение отправленных данных

Внутри обработчика обычно нужны значения, введённые пользователем. Самый удобный способ — объект FormData, который за один шаг собирает все именованные элементы управления:

const form = document.getElementById("registrationForm");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  const data = Object.fromEntries(new FormData(form));
  console.log(data.username, data.email);
  // data is a plain object: { username: "...", email: "..." }
});

Определение нажатой кнопки

Когда у формы несколько кнопок отправки (например, «Сохранить» и «Удалить»), событие submit сообщает, какая из них вызвала отправку, через event.submitter:

form.addEventListener("submit", (event) => {
  event.preventDefault();
  // event.submitter is the button element that caused submission
  console.log("Submitted via:", event.submitter?.value);
});

Использование метода .submit()

Метод .submit() инициирует отправку формы программно — непосредственно из кода, без нажатия кнопки пользователем. Он полезен, когда форму нужно отправить после выполнения определённого условия (таймер, успешная автоматическая проверка, значение, вычисленное в JavaScript).

Два нюанса делают поведение .submit() отличным от пользовательской отправки:

  • Он не генерирует событие submit, поэтому любые валидация или логика, привязанные к этому событию, пропускаются.
  • Он не запускает проверку ограничений браузера, поэтому правила required и type игнорируются.

Это сделано намеренно — исторически .submit() был предназначен для отправки без повторного запуска самого обработчика, вызвавшего его (иначе возникла бы бесконечная рекурсия). В большинстве случаев лучше использовать form.requestSubmit() (рассмотрен ниже), который ведёт себя как настоящая пользовательская отправка.

Пример: программная отправка формы

Пример ниже отправляет форму из кода сразу после загрузки страницы. Поскольку у формы нет атрибута action, данные отправляются на текущую страницу; alert показывает значение скрытого поля, чтобы вы могли видеть, что именно было бы отправлено:

<!DOCTYPE html>
<html>
<head>
  <title>Auto Submit Form Demo</title>
</head>
<body>
  <form id="autoSubmitForm">
    <input type="hidden" name="data" value="Automatic Submission" />
  </form>
  <script>
    function submitFormAutomatically() {
      document.getElementById('autoSubmitForm').submit();
      alert("Form submitted with data: " + document.getElementById('autoSubmitForm').data.value);
    }
    document.addEventListener('DOMContentLoaded', submitFormAutomatically); // Call the function when the DOM is ready
  </script>
</body>
</html>

Обратите внимание: document.getElementById('autoSubmitForm').data работает потому, что именованные элементы управления формы доступны как свойства элемента формы — form.data возвращает элемент <input name="data">, а .value читает его значение.

Предпочитайте requestSubmit() вместо submit()

form.requestSubmit() — современный и более безопасный аналог form.submit(). В отличие от .submit(), он:

  • генерирует событие submit, поэтому обработчики валидации запускаются;
  • выполняет проверку ограничений браузера и показывает встроенные подсказки об ошибках, если поле невалидно;
  • опционально принимает кнопку, чтобы задать event.submitter, например form.requestSubmit(saveButton).
const form = document.getElementById("registrationForm");
// Behaves exactly like a real user click on the submit button:
form.requestSubmit();

Если вам действительно нужно обойти обработчики, как при .submit(), но при этом всё же запустить свой обработчик, можно самостоятельно сгенерировать событие: form.dispatchEvent(new Event('submit', { cancelable: true })) — но в большинстве случаев правильным выбором будет requestSubmit().

Совместное использование .submit() с обработчиками событий

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

Пример: условная отправка формы

<form id="conditionalForm">
  Accept Terms: <input type="checkbox" id="acceptTerms">
  <button type="button" onclick="checkAndSubmit()">Submit</button>
</form>
<script>
  function checkAndSubmit() {
    var form = document.getElementById('conditionalForm');
    var termsCheckbox = document.getElementById('acceptTerms');
    if (termsCheckbox.checked) {
      form.submit();
    } else {
      alert('You must accept the terms and conditions to proceed.');
    }
  }
</script>

Этот код реализует кнопку, которая при нажатии проверяет, установлен ли флажок, прежде чем отправить форму. Если условия не приняты, пользователь получает оповещение. Обратите внимание: поскольку здесь используется form.submit(), событие submit не будет сгенерировано — замените на form.requestSubmit(), если у вас есть обработчик submit, который должен выполниться.

submit event vs. submit() vs. requestSubmit()

ПоведениеСобытие submitform.submit()form.requestSubmit()
Инициируется действием пользователяДаНет (только из кода)Нет (только из кода)
Генерирует событие submitНетДа
Выполняет проверку ограниченийн/дНетДа
Можно отменить (preventDefault)ДаНетДа (через событие)
Устанавливает event.submitterДаНетДа (передайте кнопку)

Практическое правило: слушайте событие submit для валидации и перехвата; вызывайте requestSubmit() для программной инициации отправки; прибегайте к .submit() только тогда, когда намеренно хотите обойти собственные обработчики.

Заключение

Событие submit позволяет перехватить и проверить форму до её отправки, а .submit() и requestSubmit() дают возможность отправить её из кода. Главное, что нужно запомнить: .submit() незаметно пропускает и событие submit, и валидацию — поэтому предпочитайте requestSubmit(), если только не хотите намеренно этого избежать. В сочетании с event.preventDefault() и FormData эти инструменты дают полный контроль над тем, как собираются и отправляются данные пользователя.

Для дальнейшего изучения смотрите свойства и методы форм, API проверки ограничений, события change и input для реакции на изменения в полях, а также focus и blur для взаимодействия на уровне поля.

Практика

Практика
Какие из следующих утверждений верны относительно события submit и метода submit() для форм в JavaScript?
Какие из следующих утверждений верны относительно события submit и метода submit() для форм в JavaScript?
Was this page helpful?