拦截使用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函数,但是我不喜欢这种解决方案...有很多提交表单的方法...例如,在输入时按回车键,这没有考虑。


Answers:


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在表单上设置属性更好,因为它保持了标记和功能的分离。但这只是我的两分钱。

Edit2:更新了我的示例以包括preventDefault()


这不适用于Chrome更好地工作,据我可以看到使用jsbin.com/ejoyas
Eiyrioü冯Kauyf

2
请注意,在dom中可用表格之后,需要执行附加事件代码。例如,window.onload=function() { ... }用于包装
mplungjan

什么时候该processform()函数被称为先生?

不确定,因为我不使用IE,但是我认为attachEvent参数应该为“ onsubmit”。
Gerard ONeill 2015年

这在chrome 46中不起作用,附加事件时出错,需要先加载页面
tsukimi 2015年

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');});
米歇尔

1
@Michiel虽然您提供的是与jQuery一起使用的东西,但是提供的此解决方案是不依赖jQuery的纯JS解决方案。此处的解决方案类似于使用<form onsubmit="alert('hi'); return false;">
Chris Marisic,2016年

2
@ChrisMarisic-几年了:)我无论如何都将答案更新为包括jQuery
mplungjan

17

<form onSubmit="return captureForm()"> 那应该做。确保您的captureForm()方法返回false


跟进:有没有一种方法可以捕获使用JavaScript提交的表单,而又不影响浏览器对必需属性的处理?
伊丽莎白

@Elisabeth对什么属性有什么处理?如果你的意思是不会阻止实际提交表单,您只需要captureForm()返回true代替false
kba

浏览器对“ required”属性的处理。我确实想阻止表单被提交。但是,通过返回false而不是true(或使用preventDefault()),它更改了浏览器处理输入元素上“必需”属性的方式。自己尝试:将<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 node = form.childNodes [i]; / *用节点做事/} /返回false;* /}歌剧中的测试。取消注释最后一行,必选失败。(抱歉,代码在注释中无法正常运行)
伊丽莎白

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年(或更长时间)后执行此操作的其他任何人,您都需要将click事件作为参数传递给函数(如中所述,function(e)并进行调用e.preventDefault()
digitaljoel 2013年

如果使用了input [type =“ submit”],也可以在表单的“ submit”事件中捕获该信息,这会将您置于表单上下文而不是按钮上下文中。回调将始终具有事件的上下文,因此您不必必须将“ e”作为参数传递,您只需引用“ event”即可。
augurone

1
不建议这样做,因为可以通过按键触发提交。
jhpratt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.