JavaScriptでフォーム送信を傍受し、通常の送信を防止します


82

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キーを押すと、これは考慮されません。

Ty


回答:


93
<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、マークアップと機能の分離を維持するため、フォームに属性を設定するよりも優れています。しかし、それは私の2セントです。

Edit2:私の例を更新してpreventDefault()


これはどちらか私の知る限り使用して見ることができるように、クロムでは動作しませんjsbin.com/ejoyasを
EiyrioüフォンKauyf

2
フォームがDOMで使用可能になった後で、アタッチイベントコードを実行する必要があることに注意してください。たとえば、window.onload=function() { ... }それをラップするために使用する
mplungjan 2013

processform()関数はいつ呼び出されますか?

IEを使用していないためわかりませんが、attachEventパラメーターは「onsubmit」である必要があると思います。
Gerard ONeill 2015年

これは
Chrome46

27

アタッチする要素が読み込まれる前にイベントをアタッチすることはできません

これは機能します-

プレーンJS

デモ

eventListenerの使用をお勧めします

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
    alert('hi');
  });
});

ただし、複数のリスナーが必要ない場合は、onloadとonsubmitを使用できます。

// Should only be triggered on first page load
alert('ho');

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

    // Should be triggered on form submit
    alert('hi');
    // You must return false to prevent the default form behavior
    return false;
  }
}

jQuery

// Should only be triggered on first page load
alert('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

    alert('hi');
  });
});

私はあなたが意味すると思います:$( '#my-form).on(' submit '、function(){alert(' hi ');});
ミシエル2013年

1
@Michielが提供するのは、jQueryで使用するものですが、提供されるこのソリューションは、jQueryに依存しない純粋なJSソリューションです。ここでの解決策は、使用するのと同様です<form onsubmit="alert('hi'); return false;">
Chris Marisic 2016

2
@ ChrisMarisic-数歳:)とにかく答えを更新してjQueryを含めました
mplungjan 2016

17

<form onSubmit="return captureForm()"> それで十分です。captureForm()メソッドがを返すことを確認してくださいfalse


フォローアップ:ブラウザの必要な属性の処理に影響を与えることなく、JavaScriptでフォーム送信をキャプチャする方法はありますか?
エリザベス

@Elisabethどの属性をどのように処理しますか?フォームが実際に送信されるのを妨げないようにする場合は、の代わりcaptureForm()に戻る必要があります。truefalse
kba 2011年

「必須」属性のブラウザーの処理。フォームが送信されないようにしたいのですが。ただし、trueではなくfalseを返す(またはpreventDefault()を使用する)ことにより、ブラウザーが入力要素の「必須」属性を処理する方法が変更されます。自分で試してみてください。入力要素に<code> required </ code>を追加し、送信をキャプチャして、デフォルトの動作が失われるかどうかを確認します。
エリザベス

デフォルトの動作を失うことはないようです。Chromeでは正常に動作します。私が助けるためにあなたは間違った例を思い付く必要があるでしょう。
kba 2011年

1
わかりました。フォームは次のとおりです。<formmethod = "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"); for(var i = 0; i <form.childNodes.length; i ++){var node = form.childNodes [i]; / *ノードで処理を行う/} / falseを返す; * /}オペラでのテスト。最後の行のコメントを外します。requiredは失敗します。(申し訳ありませんが、コメントではコードがうまく機能しません)
Elisabeth

6

onloadが役に立たない場合に私の練習で使用したすべてのリクエストを処理する別のオプションは、javascriptの送信、htmlの送信、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();
});

3
2。5年(またはそれ以上)後にこれを行う他の人は、クリックイベントをパラメーターとして関数に渡す必要があります(in function(e)and calle.preventDefault()
digitaljoel

input [type = "submit"]が使用されている場合は、フォームの「送信」イベントでキャプチャすることもできます。これにより、フォームのコンテキストとボタンのコンテキストが表示されます。コールバックには常にイベントのコンテキストが含まれるため、必ずしも引数として「e」を渡す必要はなく、単に「イベント」を参照するだけです。
augurone 2015

1
キーを押すと送信がトリガーされる可能性があるため、これはお勧めしません。
jhpratt 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.