17

我需要避免双击提交行为。我正在将客户端验证与不显眼的库一起使用。我有以下代码可以避免双重单击:

jQuery.fn.preventDoubleSubmit = function () {
         var alreadySubmitted = false;
         return jQuery(this).submit(function () {

             if (alreadySubmitted)
                 return false;
             else {
                 alreadySubmitted = true;
             }
         });
     };

     jQuery('form').preventDoubleSubmit();

不幸的是,如果我的表单有一些有效字段(例如,必填字段),上面的代码仍然会被触发,因此,即使我更正了表单上的任何错误,我也无法再次提交。

验证成功后如何触发双击代码?

4

9 回答 9

22

您还可以使用JQuery One 事件

我发现我可以通过快速双击来绕过大多数防止双击的防护措施。使用一个事件是确保事件只被触发一次的唯一真正方法。我认为这种技术不会在输入 type=submit 标记的情况下“开箱即用”。相反,您可以简单地使用输入 type=button 或JQueryUI 的 .button()

$("#submitButton").one("click", function(event) {
   $('#theForm').submit();
});

如果您需要在验证错误(或其他情况)上重新连接事件,我建议您为事件处理程序创建一个函数。此示例中不需要该函数,因为事件处理程序所做的只是提交表单,但在更复杂的场景中,您可能希望避免重复自己。

function submitClick(event) {
   $('#theForm').submit();
}

$("#submitButton").one('click', function(event) {
   submitClick(event);
});

// This handler will re-wire the event when the form is invalid.
$('#theForm').submit(function(event) {
   if (!$(this).valid()) {
      event.preventDefault();
      $('#submitButton').one('click', function(event) { submitClick(event); });
   }
});

如果您想向用户提供按钮不再起作用的反馈,您显然可以在此处添加禁用代码。使用 One 事件的一个很好的副作用是您实际上不必禁用按钮,您可以使用自己的样式。

function submitClick(event) {
   $('#submitButton').addClass('disabledButton');
   $('#theForm').submit();
}

$("#submitButton").one('click', function(event) {
   submitClick(event);
});

// This handler will re-wire the event when the form is invalid.
$('#theForm').submit(function(event) {
   if (!$(this).valid()) {
      event.preventDefault();
      $('#submitButton').one('click', function(event) { submitClick(event); });
      $('#submitButton').removeClass('disabledButton');
   }
});

JQuery 一事件: http ://api.jquery.com/one/

于 2011-01-05T23:13:00.443 回答
8

我用以下代码解决了它:

var tryNumber = 0;
 jQuery('input[type=submit]').click(function (event) {
     var self = $(this);

     if (self.closest('form').valid()) {
         if (tryNumber > 0) {
             tryNumber++;
             alert('Your form has been already submited. wait please');
             return false;
         }
         else {
             tryNumber++;
         }
     };
 });

注意:您还可以替换:

return false;

行,用于:

self.attr('disabled', true);

但是,如果您将控制器上的提交按钮的名称用于额外的逻辑,它们将作为 null 发送。(您可以在提交前使用额外的隐藏字段向他们收费)

就是这样,希望对你有帮助

罗德里戈

编辑:感谢这些帖子: jquery newbie: combine validate with hidding submit button

于 2010-12-28T19:00:19.670 回答
5

为什么不直接使用:

function disableButtons() {
    var form = $(this);
    var btns = $("input:submit", form);

    if (!form.valid()) {
        // allow user to correct validation errors and re-submit
        btns.removeAttr("disabled");
    } else {
        btns.attr("disabled", "disabled");
    }
}

禁用您的按钮并使用以下方法激活它:

$("form").bind("submit", disableButtons);
于 2011-10-07T15:37:01.283 回答
3

基于Ryan P 的流行回答,我创建了以下通用解决方案,该解决方案也适用于我的 ajax 表单。

使用以下类装饰您的自定义提交按钮:

<button type="button" class="one-click-submit-button">Submit</button>

将以下内容添加到您的 javascript 文件中:

function OneClickSubmitButton() {
    $('.one-click-submit-button').each(function () {
        var $theButton = $(this);
        var $theForm = $theButton.closest('form');

        //hide the button and submit the form
        function tieButtonToForm() {
            $theButton.one('click', function () {
                $theButton.hide();
                $theForm.submit();
            });
        }

        tieButtonToForm();

        // This handler will re-wire the event when the form is invalid.
        $theForm.submit(function (event) {
            if (!$(this).valid()) {
                $theButton.show();
                event.preventDefault();
                tieButtonToForm();
            }
        });
    });
}

OneClickSubmitButton();

因为这是一个 ajax 表单,所以如果服务器验证失败,我们希望重新加载处理程序。

function MyForm_OnSuccess() {
    if (true if your form passed validation logic) {
        //do something since your form submitted successfully
    } else { //validation failed on server
        OneClickSubmitButton(); //reinitialize the button logic
    }
}

显然如果你没有ajax表单你可以省略整个OneClickSubmitButton函数业务$('.one-click-submit-button').each(...直接运行。

于 2012-09-07T21:47:22.120 回答
2

我有一个使用 MVC3 不显眼验证的表单,以及一个带有 [RemoteAttribute] 的视图模型。在我看来,表单的提交事件仅在所有验证通过后才会触发。我目前正在使用它,它似乎有效:

<input type="submit" value="Submit the Form" 
    data-app-disable-on-submit="true" />

$('form').live('submit', function() {
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]')
                .attr('disabled', 'disabled');
})

;

我在远程属性验证操作方法和 HttpPost 操作方法上都设置了断点。第一次单击提交按钮会命中验证操作方法上的断点。此时,该按钮仍处于启用状态。我可以多次单击它,并且在恢复验证方法后,HttpPost 只被命中一次。当 HttpPost 被点击时,提交按钮被禁用。

更新

对,你是亚历克斯。所以上面的更新版本看起来像这样:

$('form').on('submit', function() {
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]')
                .attr('disabled', 'disabled');
})
于 2011-10-18T16:03:18.043 回答
2
 $('form').submit(function () {
 $('input[type="submit"]', this).attr('disabled', 'disabled');
   });
于 2014-05-21T10:57:30.847 回答
2

我对此使用了不同的方法。不是连接到按钮的单击事件,而是连接到表单的提交事件。就像防止多个同时提交表单的魅力一样。

function initFormsToPreventSimultaneousSubmits(selector) {
    if (!selector) {
        selector = 'form'; // No selector supplied, apply to all forms on the page
    }

    // Make sure all forms that conform to selector are marked as not submitting
    $(selector).each(function()
    {
        var $form = $(this);
        $form.data('submitting', false);
    });

    // Attach to submit event of all forms that conform to selector
    $(selector).off('submit').on('submit', function (e) {
        var $form = $(this);

        if (!$form.valid || $form.valid()) { // Make sure to only process when the form is valid or jquery validation is not used
            if ($form.data('submitting')) {
                // form is already submitting. Classic case of double click on one of the submit buttons of the form. Stop the submit
                e.preventDefault();
                return false;
            } else {
                // All ok, mark the form as submitting and let the form perform the submit
                $form.data('submitting', true);
                return true;
            }
        }
    });
}

在准备好文档时,我调用 initFormsToPreventSimultaneousSubmits() 来初始化页面上的所有表单。

唯一要记住的是,当您使用 ajax 表单发布时,是在 AjaxOptions 设置的 OnComplete 事件上调用 initFormsToPreventSimultaneousSubmits('#formId') 。因为否则表单在完成后仍将被标记为提交。当使用“正常”表单帖子时,这不是问题。

于 2014-07-22T17:49:29.040 回答
0

将AlexRyan P的答案扩展到可能缺少 jQuery 验证以及单个表单中存在多个提交按钮的情况。

oneClickSubmitButton = function () {
    $('input[type=submit], button[type=submit], input[type=image]').each(function () {
        var $theButton = $(this);
        var $theForm = $theButton.closest('form');

        //hide the button and submit the form
        function tieButtonToForm() {
            $theButton.one('click', function () {
                $theButton.addClass('ui-state-disabled');
            });
        }

        tieButtonToForm();

        $theForm.submit(function (event) {
            // Only proceed for the clicked button
            if (!$theButton.hasClass("ui-state-disabled"))
                return;

            // If jQuery Validation is not present or the form is valid, the form is valid
            if (!$theForm.valid || $theForm.valid())
                return;

            // Re-wire the event
            $theButton.removeClass('ui-state-disabled');
            event.preventDefault();
            tieButtonToForm();
        });
    });
};
于 2014-02-19T19:01:42.627 回答
0

我能够用几行代码解决类似的问题。如果您不想“提醒”用户他们双击并只是默默地忽略第二次点击,我更喜欢这个。

我刚刚创建了一个全局 javascript 变量,当我的函数在关键部分执行时我切换了它。这可以防止后续函数调用重新执行相同的部分。

 var criticalSection = false;

 SomeOnClickEventFired = function () {
      if (!criticalSection)
      {
            criticalSection = true;
            //Ajax Time
            criticalSection = false;
      }
 }
于 2015-10-12T18:57:10.803 回答