javascript - jQuery 事件处理程序如何排队和执行?

标签 javascript jquery html form-submit

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

所以我在我的表单中添加了以下 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() 中会影响它们的执行行为吗?

最佳答案

表单在提交时默认导航到设置的action url。在没有明确设置的情况下,url 是当前页面。第一个提交调用将结束启动导航过程。在此期间,当前加载的 javascript 代码被卸载。这包括事件处理程序。因此,为什么您会遇到是否能够双重提交的不一致。如果网络请求和其他页面进程对操作 url 的发生速度快于您再次单击事件处理程序所需的速度,则不会再次调用/到达您的断点,因为它们已经卸载。反之亦然,如果网络请求较慢,您将能够调用处理程序并到达断点(如果尚未卸载)。

您说您不想永久禁用提交按钮,但即使您禁用它,表单提交也会导致页面更改,在您的示例中,这只会加载具有新提交的同一页面按钮将不再被禁用,因为它是一个新页面。因此,它从一开始就永远不会真正永久禁用。

现在,如果您的真实表单实际上并没有进行正常的表单提交,并且您使用的是 ajax 请求、网络套接字连接等,那么您可以在在 ajax 请求回调、web 套接字事件等中请求和取消设置。

例如:

jQuery('form').on('submit',function(e){
  e.preventDefault();
  var fd = new FormData(this);
  jQuery('yourbutton').prop('disabled',true);
  fetch('url',{method:"post",body:fd}).then(()=>jQuery('yourbutton').prop('disabled',false));
});

关于javascript - jQuery 事件处理程序如何排队和执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55509038/

相关文章:

javascript - 丢弃的元素不可见

javascript - 使用 Angular ng-swipe-left 和 ng-swipe-right 在滑动过程中旋转图像

java - 在 Java 中显示 HTML 并与之交互

javascript - 我想在单击主体时关闭 div,但使用 .not( ) 或类似的简单函数省略父 div

javascript - 使用 Javascript 将标签添加到文本区域

加载另一个部分后,Javascript 函数仍然保留

php - 依赖下拉列表获取 id 而不是名称

html - 列表对齐方式错误

javascript - Materialise CSS on chip 删除

html - Vue js - 带有 v-for 的图像映射区域