Перехватить отправку формы в JavaScript и предотвратить нормальную отправку

84

Кажется, есть много информации о том, как отправить форму с помощью javascript, но я ищу решение для захвата, когда форма была отправлена, и перехвата ее в javascript.

HTML

<form>
 <input type="text" name="in" value="some data" />
 <button type="submit">Go</button>
</form>

Когда пользователь нажимает кнопку отправки, я не хочу, чтобы форма отправлялась, но вместо этого я хотел бы, чтобы вызывалась функция JavaScript.

function captureForm() {
 // do some stuff with the values in the form
 // stop form from being submitted
}

Быстрый взлом - добавить к кнопке функцию onclick, но мне не нравится это решение ... есть много способов отправить форму ... например, нажав клавишу возврата во время ввода, что не учитывается.

Ty

Мруустер
источник
3
Возможный дубликат Как предотвратить отправку формы?
Michał Perłakowski

Ответы:

96
<form id="my-form">
    <input type="text" name="in" value="some data" />
    <button type="submit">Go</button>
</form>

В JS:

function processForm(e) {
    if (e.preventDefault) e.preventDefault();

    /* do what you want with the form */

    // You must return false to prevent the default form behavior
    return false;
}

var form = document.getElementById('my-form');
if (form.attachEvent) {
    form.attachEvent("submit", processForm);
} else {
    form.addEventListener("submit", processForm);
}

Изменить : на мой взгляд, этот подход лучше, чем установка onSubmitатрибута в форме, поскольку он поддерживает разделение разметки и функциональности. Но это всего лишь мои два цента.

Edit2 : обновлен мой пример, чтобы включитьpreventDefault()

Майкл Мактирнан
источник
это не работает с хромом, насколько я могу видеть с помощью jsbin.com/ejoyas
Eiyrioü von Kauyf
2
Обратите внимание, что код события присоединения необходимо выполнить ПОСЛЕ того, как форма станет доступной в dom. Например, используя, window.onload=function() { ... }чтобы обернуть его
mplungjan
когда processform()функция вызывается, сэр?
Не уверен, потому что я не использую IE, но я думаю, что параметр attachEvent должен быть onsubmit.
Джерард Онил
это не работает в chrome 46, ошибка при присоединении события, сначала нужно загрузить страницу
tsukimi
29

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

Это работает -

Обычный JS

ДЕМО

Рекомендуется использовать eventListener

// Should only be triggered on first page load
console.log('ho');

window.addEventListener("load", function() {
  document.getElementById('my-form').addEventListener("submit", function(e) {
    e.preventDefault(); // before the code
    /* do what you want with the form */

    // Should be triggered on form submit
    console.log('hi');
  })
});
<form id="my-form">
  <input type="text" name="in" value="some data" />
  <button type="submit">Go</button>
</form>

но если вам не нужно более одного слушателя, вы можете использовать onload и onsubmit

// Should only be triggered on first page load
console.log('ho');

window.onload = function() {
  document.getElementById('my-form').onsubmit = function() {
    /* do what you want with the form */

    // Should be triggered on form submit
    console.log('hi');
    // You must return false to prevent the default form behavior
    return false;
  }
}
    <form id="my-form">
      <input type="text" name="in" value="some data" />
      <button type="submit">Go</button>
    </form>

jQuery

// Should only be triggered on first page load
console.log('ho');

$(function() {
  $('#my-form').on("submit", function(e) {
    e.preventDefault(); // cancel the actual submit

    /* do what you want with the form */

    // Should be triggered on form submit

    console.log('hi');
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="my-form">
  <input type="text" name="in" value="some data" />
  <button type="submit">Go</button>
</form>

mplungjan
источник
Я думаю, вы имеете в виду: $ ('# my-form) .on (' submit ', function () {alert (' hi ');});
Michiel
1
@Michiel, в то время как то, что вы предоставляете, - это то, что вы используете с jQuery, это предоставленное решение представляет собой чистое решение JS, не зависящее от jQuery. Решение здесь было бы похоже на использование<form onsubmit="alert('hi'); return false;">
Крис Марисич
2
@ChrisMarisic - несколько лет назад :) Я все равно обновил ответ, включив jQuery
mplungjan
17

<form onSubmit="return captureForm()"> это должно сработать. Убедитесь, что ваш captureForm()метод возвращается false.

кба
источник
Последующие действия: есть ли способ зафиксировать отправку формы с помощью JavaScript, не влияя на обработку браузером обязательного атрибута?
Элизабет
@Elisabeth Какая обработка какого атрибута? Если вы хотите не препятствовать фактической отправке формы, вам просто нужно captureForm()вернуться trueвместо false.
kba
Обработка браузером «обязательного» атрибута. Я действительно хочу предотвратить отправку формы. Но, возвращая false вместо true (или используя preventDefault ()), он меняет способ обработки браузером «обязательного» атрибута в элементе ввода. Попробуйте сами: добавьте <code> required </code> к элементу ввода, зафиксируйте отправку и посмотрите, не потеряете ли вы для него поведение по умолчанию.
Элизабет
Я не теряю поведения по умолчанию. Он отлично работает в Chrome. Чтобы я мог помочь, вам нужно придумать ошибочный пример.
kba
1
Хорошо, вот форма: <form method = "get" action = ""> <label for = "color"> Какой ваш любимый цвет? </label> <input type = "text" name = "color" placeholder = "blue" required> <input id = "submit" type = "submit" value = "Submit"> </form> и вот код: function processForm (e) {var form = document.querySelector ("form"); для (var i = 0; i <form.childNodes.length; i ++) {var node = form.childNodes [i]; / * что-то делать с узлами /} / return false; * /} Тестирование в опере. Раскомментируйте последнюю строку, требовать не удается. (Извините, код не работает в комментариях)
Элизабет
6

Другой вариант обработки всех запросов, которые я использовал в своей практике для случаев, когда onload не может помочь, - это обработка запросов javascript submit, html submit, ajax. Этот код должен быть добавлен в верхнюю часть элемента body, чтобы создать слушателя перед визуализацией и отправкой любой формы.

В примере я установил скрытое поле для любой формы на странице при ее отправке, даже если это происходит до загрузки страницы.

//Handles jquery, dojo, etc. ajax requests
(function (send) {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    XMLHttpRequest.prototype.send = function (data) {
        if (isNotEmptyString(token) && isNotEmptyString(header)) {
            this.setRequestHeader(header, token);
        }
        send.call(this, data);
    };
})(XMLHttpRequest.prototype.send);


//Handles javascript submit
(function (submit) {
    HTMLFormElement.prototype.submit = function (data) {
        var token = $("meta[name='_csrf']").attr("content");
        var paramName = $("meta[name='_csrf_parameterName']").attr("content");
        $('<input>').attr({
            type: 'hidden',
            name: paramName,
            value: token
        }).appendTo(this);

        submit.call(this, data);
    };
})(HTMLFormElement.prototype.submit);


//Handles html submit
document.body.addEventListener('submit', function (event) {
    var token = $("meta[name='_csrf']").attr("content");
    var paramName = $("meta[name='_csrf_parameterName']").attr("content");
    $('<input>').attr({
        type: 'hidden',
        name: paramName,
        value: token
    }).appendTo(event.target);
}, false);
Виталий Борисок
источник
2

Используйте ответ @Kristian Antonsen, или вы можете использовать:

$('button').click(function() {
    preventDefault();
    captureForm();
});
rsplak
источник
4
для всех, кто делает это через 2,5 года (или больше), вам необходимо передать событие щелчка в качестве параметра функции (как in function(e)и calle.preventDefault()
digitaljoel
Также может быть зафиксировано в событии «submit» для формы, если ваш input [type = «submit»] используется, и это помещает вас в контекст формы, а не в контекст кнопки. Обратный вызов всегда будет иметь контекст события, поэтому вам не обязательно передавать «e» в качестве аргумента, вы просто ссылаетесь на «событие».
Авгурон
1
Это не рекомендуется, поскольку отправка может быть инициирована нажатием клавиши.
jhpratt 01