Fangen Sie eine Formularübermittlung in JavaScript ab und verhindern Sie die normale Übermittlung

84

Es scheint viele Informationen darüber zu geben, wie ein Formular mit Javascript gesendet werden kann, aber ich suche nach einer Lösung, um zu erfassen, wann ein Formular gesendet wurde, und es in Javascript abzufangen.

HTML

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

Wenn ein Benutzer auf die Schaltfläche "Senden" drückt, möchte ich nicht, dass das Formular gesendet wird, sondern dass eine JavaScript-Funktion aufgerufen wird.

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

Ein schneller Hack wäre, der Schaltfläche eine Onclick-Funktion hinzuzufügen, aber diese Lösung gefällt mir nicht ... es gibt viele Möglichkeiten, ein Formular zu senden ... z. B. die Eingabetaste zu drücken, während eine Eingabe ausgeführt wird, was dies nicht berücksichtigt.

Ty

mrwooster
quelle
3
Mögliches Duplikat von Wie kann verhindert werden, dass ein Formular eingereicht wird?
Michał Perłakowski

Antworten:

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

In 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);
}

Bearbeiten : Meiner Meinung nach ist dieser Ansatz besser als das Festlegen des onSubmitAttributs im Formular, da die Trennung von Markup und Funktionalität beibehalten wird. Aber das sind nur meine zwei Cent.

Edit2 : Mein Beispiel wurde aktualisiert, um es einzuschließenpreventDefault()

Michael McTiernan
quelle
Dies funktioniert auch nicht mit Chrom, soweit ich mit jsbin.com/ejoyas
Eiyrioü von Kauyf sehen kann
2
Beachten Sie, dass der Ereigniscode zum Anhängen ausgeführt werden muss, nachdem das Formular im Dom verfügbar ist. Zum Beispiel mit window.onload=function() { ... }, um es zu verpacken
mplungjan
Wann wird die processform()Funktion Sir genannt?
Ich bin mir nicht sicher, weil ich keinen IE verwende, aber ich denke, der Parameter attachEvent sollte "onsubmit" sein.
Gerard ONeill
Dies funktioniert nicht in Chrome 46, Fehler beim Anhängen eines Ereignisses, muss die Seite zuerst laden
Tsukimi
29

Sie können keine Ereignisse anhängen, bevor die Elemente, an die Sie sie anhängen, geladen wurden

Das funktioniert -

Plain JS

DEMO

Empfohlen, eventListener zu verwenden

// 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>

Wenn Sie jedoch nicht mehr als einen Listener benötigen, können Sie onload und onsubmit verwenden

// 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
quelle
Ich denke du meinst: $ ('# my-form) .on (' submit ', function () {alert (' hi ');});
Michiel
1
@Michiel Während Sie das bereitstellen, was Sie mit jQuery verwenden, handelt es sich bei dieser bereitgestellten Lösung um eine reine JS-Lösung ohne Abhängigkeit von jQuery. Die Lösung hier wäre ähnlich wie bei<form onsubmit="alert('hi'); return false;">
Chris Marisic
2
@ ChrisMarisic - ein paar Jahre alt :) Ich habe die Antwort trotzdem aktualisiert, um jQuery
mplungjan
17

<form onSubmit="return captureForm()"> das sollte reichen. Stellen Sie sicher, dass Ihre captureForm()Methode zurückgegeben wird false.

kba
quelle
Follow-up: Gibt es eine Möglichkeit, ein Formular mit JavaScript zu erfassen, ohne die Handhabung des erforderlichen Attributs durch den Browser zu beeinträchtigen?
Elisabeth
@ Elizabeth Welcher Umgang mit welchem ​​Attribut? Wenn Sie meinen , nicht die Form verhindern , dass tatsächlich vorgelegt werden, müssen Sie nur captureForm()zurück truestatt false.
kba
Die Behandlung des "erforderlichen" Attributs durch den Browser. Ich möchte verhindern, dass das Formular gesendet wird. Durch die Rückgabe von false anstelle von true (oder durch die Verwendung von PreventDefault ()) wird jedoch geändert, wie der Browser mit dem Attribut "required" für ein Eingabeelement umgeht. Probieren Sie es aus: Fügen Sie einem Eingabeelement <code> required </ code> hinzu, erfassen Sie die Übermittlung und prüfen Sie, ob Sie das Standardverhalten dafür verlieren.
Elisabeth
Ich scheine das Standardverhalten nicht zu verlieren. In Chrome funktioniert es einwandfrei. Sie müssen sich ein fehlerhaftes Beispiel einfallen lassen, damit ich Ihnen helfen kann.
kba
1
Ok, hier ist das Formular: <form method = "get" action = ""> <label for = "color"> Was ist Ihre Lieblingsfarbe? </ Label> <input type = "text" name = "color" placeholder = "blau" erforderlich> <input id = "submit" type = "submit" value = "Submit"> </ form> und hier ist der Code: function processForm (e) {var form = document.querySelector ("form"); für (var i = 0; i <form.childNodes.length; i ++) {var node = form.childNodes [i]; / * mache Sachen mit Knoten /} / return false; * /} Testen in der Oper. Das Kommentieren der letzten erforderlichen Zeile schlägt fehl. (Sorry Code funktioniert nicht gut in Kommentaren)
Elisabeth
6

Eine weitere Option zur Bearbeitung aller Anfragen, die ich in meiner Praxis für Fälle verwendet habe, in denen Onload nicht helfen kann, ist die Bearbeitung von Javascript-Submit-, HTML-Submit- und Ajax-Anfragen. Dieser Code sollte oben im body-Element hinzugefügt werden, um einen Listener zu erstellen, bevor ein Formular gerendert und gesendet wird.

In einem Beispiel habe ich ein ausgeblendetes Feld auf ein Formular auf einer Seite gesetzt, auch wenn es vor dem Laden der Seite auftritt.

//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);
Vitaliy Borisok
quelle
2

Verwenden Sie die Antwort von @Kristian Antonsen, oder verwenden Sie:

$('button').click(function() {
    preventDefault();
    captureForm();
});
rsplak
quelle
3
Für alle anderen, die dies 2,5 Jahre (oder länger) später tun, müssen Sie das function(e)e.preventDefault()
Klickereignis
Kann auch beim "Submit" -Ereignis für das Formular erfasst werden, wenn Ihre Eingabe [type = "submit"] verwendet wird und Sie sich damit im Formularkontext gegenüber dem Kontext der Schaltfläche befinden. Der Rückruf hat immer den Kontext des Ereignisses, sodass Sie nicht unbedingt "e" als Argument übergeben müssen, sondern sich einfach auf "Ereignis" beziehen.
Augurone
1
Dies wird nicht empfohlen, da die Übermittlung per Tastendruck ausgelöst werden kann.
Jhpratt