拦截 JavaScript 中的表单提交,阻止正常提交

IT技术 javascript html forms
2021-02-10 07:00:50

似乎有很多关于如何使用 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 功能,但我不喜欢这个解决方案......有很多方法可以提交表单......例如在输入时按回车,这并没有说明。

6个回答
<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 46 中不起作用,附加事件时出错,需要先加载页面
2021-03-19 07:00:50
请注意,附加事件代码需要在表单在 dom 中可用后执行。例如window.onload=function() { ... }用于包装它
2021-03-21 07:00:50
就我使用jsbin.com/ejoyas 所见,这也不适用于 chrome
2021-03-22 07:00:50
不确定,因为我不使用 IE,但我认为 attachEvent 参数应该是“onsubmit”。
2021-03-30 07:00:50
什么时候processform()调用函数sir?
2021-04-02 07:00:50

您无法在附加事件的元素加载之前附加事件

这有效 -

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

太感谢了 :)
2021-04-01 07:00:50
@ChrisMarisic - 几岁了 :) 我已经更新了答案以包含 jQuery
2021-04-03 07:00:50
@Michiel 虽然您提供的是与 jQuery 一起使用的内容,但提供的此解决方案是纯 JS 解决方案,不依赖于 jQuery。这里的解决方案类似于使用<form onsubmit="alert('hi'); return false;">
2021-04-08 07:00:50
我想你的意思是: $('#my-form).on('submit', function() { alert('hi'); });
2021-04-11 07:00:50

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

我似乎没有失去默认行为。它在 Chrome 中运行良好。你需要想出一个错误的例子来帮助我。
2021-03-21 07:00:50
@Elisabeth 处理什么属性?如果您的意思是不阻止实际提交表单,则只需要captureForm()returntrue而不是false.
2021-03-28 07:00:50
好的,这是表单:<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"); for (var i = 0; i < form.childNodes.length; i++) { var node = form.childNodes[i]; /* 对节点做一些事情/ } / return false; */ } 在歌剧中测试。取消注释最后一行, required 失败。(抱歉代码在注释中不起作用)
2021-04-02 07:00:50
浏览器对“必需”属性的处理。我确实想阻止提交表单。但是通过返回 false 而不是 true(或使用 preventDefault()),它会改变浏览器处理 input 元素上的“required”属性的方式。亲自尝试一下:将 <code>required</code> 添加到输入元素,捕获提交并查看是否丢失了它的默认行为。
2021-04-07 07:00:50
跟进:有没有办法在不影响浏览器对所需属性的处理的情况下使用 JavaScript 捕获表单提交?
2021-04-13 07:00:50

在 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);

使用@Kristian Antonsen 的回答,或者您可以使用:

$('button').click(function() {
    preventDefault();
    captureForm();
});
不建议这样做,因为可以通过按键触发提交。
2021-03-19 07:00:50
对于 2.5 年(或更长时间)后执行此操作的任何其他人,您需要将 click 事件作为参数传递给函数(如 in function(e)and calle.preventDefault()
2021-03-22 07:00:50
也可以在表单的“提交”事件上捕获,如果您使用 input[type="submit"],并且这会将您置于表单上下文与按钮的上下文中。回调将始终具有事件的上下文,因此您不必将 'e' 作为参数传递,您只需引用 'event'。
2021-03-29 07:00:50