Форма, отправленная с помощью submit() из ссылки, не может быть захвачена обработчиком onsubmit

Удивленный, я сталкиваюсь с этой странной проблемой при отправке формы из JS.

Проблема:

Рассмотрим простую форму, представленную двумя способами с помощью кнопки submit и anchor link

<form method="POST" action="page.html" name="foobar" id="test">
  <input type="text" />
  <input type="submit" />
</form>

<a href="#" onclick="document.getElementById('test').submit();">click me</a>

Функция ловить событие отправки

document.getElementById('test').onsubmit = function() {
   // Same result with 
   //     * document.foobar.onsubmit
   //     * document.forms['foobar'].onsubmit

   alert('foobar');
   return false;
}

Теперь, когда форма отправляется после нажатия кнопки submit, я получаю предупреждение, но не при нажатии ссылки. Почему это происходит?

Скриншот, показывающий проблему

Ответ 1

Чтобы дать разумно окончательный ответ, алгоритм представления формы HTML, пункт 5 гласит, что форма только отправляет событие отправки, если оно не было отправлено путем вызова метода отправки (что означает, что он отправляет только событие отправки, если оно отправлено кнопкой или другим неявным методом, например, нажимайте enter, пока фокус находится на текстовом элементе типа ввода).

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

Это отличается от спецификации HTML DOM 2, в которой говорится, что метод отправки должен делать то, что делает кнопка отправки.

Итак, если вы хотите использовать script для отправки формы, вы должны вручную вызвать слушателя. Если слушатель был добавлен с помощью addEventListener, вам необходимо запомнить это и вызвать его, так как вы не можете его обнаружить, проверив форму (как предложено ниже).

Если слушатель установлен в строке или добавлен в свойство DOM onsubmit, вы можете сделать что-то вроде:

<form onsubmit="return validate(this);" ...>
  ...
</form>
<button onclick="doSubmit()">submit form</button>

<script>
function doSubmit() {
  var form = document.forms[0];

  if (form.onsubmit) {
    var result = form.onsubmit.call(form);
  }

  if (result !== false) {
    form.submit();
  }
}
</script>

Жизнь более жесткая, если вам нужно передать параметры или сделать другие вещи.

Ответ 2

Вот как form.submit ведет себя;

Форма onsubmit обработчик события (например, onsubmit = "return false;" ) не будет срабатывать при вызове этого метода из Приложения на базе Gecko. В общем, не гарантируется вызывается пользовательскими агентами HTML

Сделайте onsubmit вызовом функции и просто вызовите это onclick.