使用“提交”回调和$ .ajax发布时多次提交表单

我用以下代码观察了一些奇怪的行为:

$.fn.submit_to_remote = function() { // I use .each instead of the .submit directly so I can save // the 'submitEnabled' variable separately for each form jQuery.each($(this), function() { $(this).submit(function() { form = $(this); if (form.data('submitEnabled') == false) { alert('disabled'); return false; } form.data('submitEnabled', false); $.ajax({type: 'POST', url: 'url', data: data, dataType: 'script', success: function(script) { alert('success') } }) return false; }) }) } $('.submit_to_remote').submit_to_remote(); 

因此,基本上,在表单上调用submit_to_remote时,它将禁用它的正常提交,然后发出AJAX POST请求。

奇怪的是,表单会多次发布,因为“禁用”警报会显示。 正如您所看到的,我通过使用保存在表单对象上的“变量”并检查该变量以查看表单是否已提交来阻止此操作。

经过进一步测试,似乎罪魁祸首是AJAX调用返回的脚本。 让我解释一下我正在做什么,所以它更清楚。

表单将发布到服务器,并返回一个脚本。 该脚本再次显示该表单,但这次是某些字段的错误消息。 请注意,表单已完全替换。

显示新表单时,脚本执行以下操作:

 $('.submit_to_remote').submit_to_remote(); 

我必须这样做,因为否则,当你再次点击提交按钮时,表单正常提交,没有AJAX。

因此,假设用户提交表单并将其返回并显示相应的错误(未显示“已禁用”警报)。 然后他再次提交; 这次“禁用”警报会显示一次。 现在他再次提交它,这次警报显示两次! 等等…

因此,似乎每次请求都会一次又一次地附加.submit回调,但为什么呢?

可能是因为使用.html()原始forms被保留为幽灵或其他东西?

谢谢!

PS:如果它是相关的,这是$ .ajax调用返回的脚本:

 replace_content_with = 'the form and other stuff here'; $('.page-content').html(replace_content_with); $('.submit_to_remote').submit_to_remote(); 

是的,我同意Seb,这是一个很好的做法,在我看来总是在绑定之前取消绑定,除非你确定目前没有你想要的元素绑定。 你可以通过简单地使用’.submit’,’。click“,’.mouseover’等函数来双重绑定你的东西。

养成这样做的习惯(对我来说永远不会失败):

 $('.some_element').unbind('submit').bind('submit',function() { // do stuff here... }); 

… 代替:

 $('.some_element').submit(function() { // do stuff here... }); 

Unbind对我不起作用。 这样做:

 $(document).off('submit'); $(document).on('submit',"#element_id",function(e){ e.preventDefault(); //do something }); 

我希望它有帮助……

事实上,如果你在提交之前进行了一些validation并返回,unbind()会给你带来一些麻烦。 例:

 $(document).on('submit',"#element_id",function(e){ e.preventDefault(); $(document).unbind('submit'); var name = $(this).children('input[name="name"]').val(); if( name == 'wrong name') return; //do something }); 

在这种情况下,如果您输入的是“错误的名称”,则表单将不会被提交,之后,当您输入“正确的名称”时,$(文档).on(’submit’..将不会被触发,也不会被触发e.preventDefault();您的表单将以常规方式提交。

不确定这种奇怪的行为,但似乎取消绑定提交事件将成功。

因此,在运行$ .ajax调用返回的脚本之前,运行以下命令:

 $('.submit_to_remote').unbind("submit"); 

这应该删除以前的绑定,只留下新的绑定。

更容易:

 $(".some-class").off().submit(function() { //Do stuff here }); 

请记住,jQuery submit()事件在表单中查找: , , or ( http:// api。 jquery.com/submit/ )。 某些框架将type属性默认为“submit”,因此如果您尝试覆盖默认值,请将type属性更改为其他内容,以使其不会多次提交。

发生OpenCart双提交是因为common.js有一个提交绑定。

通过使用与"form-" 匹配的表单的id模式来避免这种情况。

示例:

您可以使用此代码来解决:

 $(this).submit(function() { . . . }); $(this).unbind("submit"); 

我有同样的问题,并使用点击修复如下。

  $('.submit_to_remote').on('click', function(){ //Some validation or other stuff $(this).submit(); });