Перехопіть подання форми в 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 до кнопки, але мені це рішення не подобається ... є багато способів подати форму ... наприклад, натискання return під час введення, чого це не враховує.

Тай


Відповіді:


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
Зверніть увагу, що код події вкладення потрібно виконати ПІСЛЯ форми, доступної в домі. Наприклад, використовуючи 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>


Думаю, ви маєте на увазі: $ ('# 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.
кба

Обробка браузером атрибута "необхідний". Я хочу не допустити надсилання форми. Але повертаючи false замість true (або використовуючи prevenDefault ()), це змінює спосіб обробки браузером атрибута "необхідний" для елемента введення. Спробуйте самі: додайте <code> required </code> до елемента введення, захопіть подання та перевірте, чи не втрачаєте ви поведінку за замовчуванням для нього.
Елізабет

Здається, я не втрачаю поведінку за замовчуванням. Це чудово працює в Chrome. Вам потрібно буде придумати помилковий приклад, щоб я міг допомогти.
kba

1
Гаразд, ось форма: <form method = "get" action = ""> <label for = "color"> Який ваш улюблений колір? </label> <input type = "text" name = "color" placeholder = потрібен "синій"> <input id = "submit" type = "submit" value = "Submit"> </form> і ось код: function processForm (e) {var form = document.querySelector ("form"); for (var i = 0; i <form.childNodes.length; i ++) {вузол var = form.childNodes [i]; / * робити речі з вузлами /} / return false; * /} Тестування в опері. Розкоментуйте останній рядок, необхідні помилки. (Вибачте, код не працює добре в коментарях)
Елізабет

6

Інший варіант обробки всіх запитів, які я використовував у своїй практиці для випадків, коли onload не може допомогти, - це обробка записів javascript, 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();
});

4
для будь-кого іншого, хто робить це через 2,5 роки (або більше), вам потрібно передати подію кліку як параметр функції (як у function(e)та викликe.preventDefault()
digitaljoel

Також може бути зафіксовано у події "submit" для форми, якщо використовується ваш вхід [type = "submit"], і це переводить вас у контекст форми проти контексту кнопки. Зворотний виклик завжди матиме контекст події, тому вам не обов’язково передавати аргумент "e", ви просто посилаєтесь на "подія".
augurone

1
Це не рекомендується, оскільки подання може бути викликане натисканням клавіші.
jhpratt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.