首页 > 解决方案 > jQuery 事件处理程序是如何排队和执行的?

问题描述

我有一个带有提交按钮的输入表单。我不希望用户能够双击提交按钮并双重提交表单......

所以我在我的表单中添加了以下 jQuery:

var prevSubmitTime = new Date('2000-01-01');

function preventFromBeingDoubleSubmitted() {
    $('form').each(function () {
        $(this).submit(function (e) {
            if ($("form").valid()) {
                var curSubmitTime = new Date($.now());

                // prevent the second submit if it is within 2 seconds of the first submit
                if (curSubmitTime - prevSubmitTime < 2000) {
                    e.preventDefault();
                }
                prevSubmitTime = new Date($.now());
            }
        });
    });
}

$(document).ready(function () {
    preventFromBeingDoubleSubmitted();
});

上面的代码存储了提交时间并防止了第二次提交,如果太早(小于2秒),我不想永久禁用提交按钮,以防出现服务器端错误......

e.preventDefault();这段代码可以满足我的要求,但是在调试代码时,即使我双击提交按钮,我也永远无法在 ... 上遇到断点。

看起来第二个提交事件正在等待第一个提交事件在触发之前完成。

但是,如果我删除preventFromBeingDoubleSubmitted()功能,那么我将能够通过双击提交按钮来双重提交表单。

谁能解释为什么有时提交事件会一个接一个地立即触发......有时情况并非如此?将事件处理程序放在里面.each()会影响它们的执行行为吗?

标签: javascriptjqueryhtmlform-submit

解决方案


在您的代码段中,我添加了一些可能有用的日志。由于您提出的问题不止一个,我将一一回答。

var prevSubmitTime = new Date('2000-01-01');

function preventFromBeingDoubleSubmitted() {
    $('form').each(function () {
        $(this).submit(function (e) {
            console.log('I am going to submit form');
            if ($("form").valid()) {
                var curSubmitTime = new Date($.now());
		console.log('I am a valid form')
                // prevent the second submit if it is within 2 seconds of the first submit
                if (curSubmitTime - prevSubmitTime < 2000) {
                    console.log('A small time difference. So I am stopping')
                    e.preventDefault();
                }
                prevSubmitTime = new Date($.now());
            }
        });
    });
}

$(document).ready(function () {
    preventFromBeingDoubleSubmitted();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>

<form id="myform">
    <input type="text" name="q" required="required" />
    <br />
    <input type="text" name="bar" required="required" />
    <br />
    <br />
    <input type="submit" />
</form>

谁能解释为什么有时提交事件会一个接一个地立即触发......有时情况并非如此?

我想你自己已经回答了这个问题。您正在添加代码以检查您第一次单击提交按钮与第二次单击提交按钮的时间是否存在差异。如果存在时间差,则停止第二次表单提交。

我永远无法在 e.preventDefault(); 上达到断点;

您无法获得控制台的原因是,当您单击提交按钮时,您正在重定向离开该页面。所以控制台被清除了。如果要查看控制台,请使用 ajax 函数提交表单。在返回时,您可能可以将页面重定向到某个地方。

将事件处理程序放在 .each() 中会影响它们的执行行为吗?

不,它只是一个迭代器。它不会影响提交功能。

我添加了指向 jsfiddle 的链接。在 preventDefault 之前添加警报将暂时停止页面重定向。这将证明执行发生了。

http://jsfiddle.net/2vugwyfe/


推荐阅读