Странное поведение html form submit

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

Естественно, при отправке данных на сервер, необходимо было воспользоваться JavaScript методом form.submit (). Каково же было мое удивление, когда я обнаружил, что метод отправки данных с помощью кнопки submit и работа JavaScript метода формы submit () кардинально отличаются.

Для того чтобы наглядно продемонстрировать поведение данных методов, я приведу их исходники и примеры работы.

Пример отправки данных на сервер (post) с помощью обычной кнопки <input type="submit" /> и предварительная обработка onsubmit будет выглядеть так:

<html>
<body>
  <form name="myform" onsubmit="alert('Отправка данных на сервер')" method="post">
    <input type="text" name="data" value="Данные" />
    <a href="javascript:document.myform.submit()">Отправить</a>
  </form>
</body>
</html>

при таком коде HTML, поведение формы будет следующим: если нажать кнопку «Отправить», сначала выскочит окошко с предупреждением об отправке данных на сервер, а после нажатия на кнопку «ОК», данные будут отправлены на сервер.

Form Submit

А что же будет, если заменить кнопку submit на JavaScript метод form.submit ()?

<html>
<body>
  <form name="myform" onsubmit="alert('Отправка данных на сервер')" method="post">
    <input type="text" name="data" value="Данные" />
    <a href="javascript:document.myform.submit()">Отправить</a>
  </form>
</body>
</html>

а вот в этом случае, и произойдет то самое, странное поведение формы — событие onsubmit не сработает, но данные будут отправлены на сервер.

После длительных опытов, было определено, что браузеры не следуют спецификации HTML. События обрабатываются только действиями пользователя, но не программными действиями.

А что же по этому поводу говорит спецификация W3C и основные производители браузеров.

Спецификация W3C Document Object Model (DOM) Level 2 HTML Specification говорит, что метод  submit () — «submits the form. It performs the same action as a submit button.» (сабмитит форму. Определяет то же действие, что и кнопка submit).

Производитель браузера FireFox, компания Mozilla сообщает, что onsubmit «Executes JavaScript code when a submit event occurs; that is, when a user submits a form.» (выполняет JavaScript код, когда возникает событие submit; это происходит в тот момент, когда пользователь сабмитит форму). Заметьте, что они уточняют «когда пользователь...», это в принципе исключает сабмит формы при вызове метода JavaScript.

Так же пишет и компания Netscape/Sun.

У Microsoft более лаконичное описание, «The submit method does not invoke the onsubmit event handler.» (Метод submit не вызывает событие onsubmit).

Как же выйти из этой ситуации?

Одним из решений может быть создание невидимой кнопки submit и вызов ее метода click (). Но это не сильно красивое решение. Поэтому можно подключить библиотеку jQuery и написать несколько строк кода на JavaScript для программной генерации событий.

$.fn.fireEvent = function(eventType) {
  return this.each(function() {
    if (document.createEvent) {
      var event = document.createEvent("HTMLEvents");
      event.initEvent(eventType, true, true);
      return !this.dispatchEvent(event);
    } else {
      var event = document.createEventObject();
      return this.fireEvent("on" + eventType, event)
    }
  });
};

Использовать данный метод очень просто. С помощью селектора jQuery находим нужный нам объект и вызываем метод fireEvent (), передав ему в качестве параметра, имя нужного события, без приставки on.

$("myform").fireEvent("submit");

На просторах сети, я находил еще одно решение — это использование метода trigger (), вместо метода fireEvent (), только он тоже не работает так как надо, потому и не буду его приводить тут.


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


Категории: JavaScript, Верстка, HTML, CSS  Теги: , ,
  1. 4 февраля 2010 17:38 | №1 | progg.ru

    Странное поведение html form submit | Генеральский чай...

    Thank you for submitting this cool story — Trackback from progg.ru...

  1. Frozik どみてり
    27 июля 2009 14:58 | №2

    Любопытно, но у меня следующее работает без проблем :wink: :

    $(document).ready (function () {

    $('form').submit (function () {

    alert ('Gotcha');

    });

    $('#js-submit').click (function () {

    $('form').submit ();

    });

    });

  2. 27 июля 2009 15:04 | №3

    так речь идет немного не о том. Не срабатывает именно event onsubmit

  3. Frozik どみてり
    27 июля 2009 15:13 | №4

    Ну как бы покопался и нашёл это —

    www.w3.org/TR/REC-html40/...act/scripts.html

    секция 18.2.3 Intrinsic events

    It is possible to associate an action with a certain number of events that occur when a user interacts with a user agent. Each of the «intrinsic events» listed above takes a value that is a script. The script is executed whenever the event occurs for that element. The syntax of script data depends on the scripting language.

  4. 27 июля 2009 15:16 | №5

    как-то странно, что W3C сами себе противоречат.

    Спецификация W3C Document Object Model (DOM) Level 2 HTML Specification говорит, что метод submit () — «submits the form. It performs the same action as a submit button.»

  5. Егор
    20 декабря 2011 22:03 | №6

    Вобще-то нет необходимости генерировать событие при программном вызове метода, раз JS сам метод вызывает, то значит мы итак котролируем последовательность действий. Другое дело что такое объяснение предполагает вызов события вручную на случай, если какой-то обработчик уже висит.

  6. Алесс
    1 марта 2016 8:48 | №7

    Оба кода одинаковы!! В первом коде строчку

    Отправить

    заменить на:

    Статья интересная, тоже влип в эту стенку

  7. Алесс
    1 марта 2016 8:49 | №8

    Гыыы!!!

:D :) ^_^ :( :o 8) ;-( :lol: xD :wink: :evil: :p :whistle: :woot: :sleep: =] :sick: :straight: :ninja: :love: :kiss: :angel: :bandit: :alien: