jQuery:仅当页面上当前没有运行AJAX时才提交表单

当城市输入字段模糊时,我通过ajax请求得到somne​​thing,并将其设置为与城市字段所在的相同forms的隐藏字段的值。

$('input#city').on('blur', function() { $.ajax({ url: 'get/something?param=val', success: function(response) { $('input:hidden[name="something"]').val(response); } }); }); 

如果用户在模糊城市字段后立即提交表单,有时由于延迟,则不会填充隐藏字段,因为另一端的SQL花费的时间太长。

这两个字段所在的表单也是通过ajax提交的:

 $('form#find-users').on('submit', function() { if(NO_AJAX_CURRENTLY_RUNNING_ON_PAGE) { // do stuff } }); 

如何检测页面上是否没有运行ajax? 这将确保完成城市ajax并在处理表单之前填充隐藏字段。

编辑

实际上它不会,它只会阻止提交表单。 但是,如果我可以检测到那么我可以使用setInterval并继续尝试运行该代码,直到它运行因为ajax完成。 理想情况下,jQuery中会有一些东西等待其他ajax完成然后提交。

使用jQuery的Ajax事件 。 只要使用jQuery生成所有Ajax调用,您就可以知道是否有任何Ajax调用未完成。

 $(document).ready(function() { var ajaxBusy = false; $(document).ajaxStart( function() { ajaxBusy = true; }).ajaxStop( function() { ajaxBusy = false; }); }); 

编辑:

所以这回答了你直接的问题:“如何知道是否有任何Ajax调用正在运行。”

或者,您可以在运行模糊处理程序时禁用表单的提交按钮,然后在完成后重新启用它。

 $('input#city').on('blur', function() { var submit = $(this).closest('form').find(':submit:enabled'); submit.prop('disabled', true); $.ajax('get/something?param=val').done(function(response) { $('input:hidden[name="something"]').val(response); }).always(function() { submit.prop('disabled', false); }); }); 

编辑2:

所以现在我们就要延迟表单提交,直到所有当前的Ajax调用完成。 我们让人们点击提交按钮,但如果有待处理的Ajax调用,我们就不会马上做任何事情。

我们可以使用Deferred对象来帮助我们。

 $(document).ready(function() { var ajaxDefer = $.Deferred().resolve(); $(document).ajaxStart( function() { ajaxDefer = $.Deferred(); }).ajaxStop( function() { ajaxDefer.resolve(); }); $('form#find-users').on('submit', function() { ajaxDefer.always(function() { // Code here will always be executed as soon as there are no // Ajax calls running. // this points to the deferred object (ajaxDefer), so use the closure // to carry over any variables you need. }); }); }); 
  1. 当我们刚刚开始时,我们将ajaxDefer对象设置为已解析状态。 这意味着使用.always()附加的任何函数都会立即执行。

  2. 当第一个Ajax调用开始时,我们将旧的ajaxDefer对象替换为尚未解析的新对象。 使用ajaxDefer.always()附加的任何新函数将推迟到以后。

  3. 当最后一个Ajax调用完成时,我们调用ajaxDefer.resolve() ,这会导致执行任何未执行的延迟函数。 现在我们回到初始状态,任何新附加的函数将立即执行。

  4. 当有人试图提交表单时,创建一个匿名函数来完成工作并将其附加到ajaxDefer 。 它将在适当时执行,具体取决于是否有任何未完成的Ajax请求。 注意你的关闭。

使用它来使用JQuery检查AJAX调用当前是否正在进行中:

 if ($.active == 0) { ... } 

您可以在全局命名空间中放置一个变量,可能名为ajaxLock并在AJAX启动时将其切换为ajaxLock ,并在响应到来时关闭。 然后在允许提交之前检查它。

就像是

 var ajaxLock = 1; $('input#city').on('blur', function() { $.ajax({ url: 'get/something?param=val', success: function(response) { $('input:hidden[name="something"]').val(response); ajaxLock = 0; } }); }); 

使用你建议的锁定变量:

 $('input#city').on('blur', function() { window.AJAX_CURRENTLY_RUNNING_ON_PAGE = true; $.ajax({ url: 'get/something?param=val', success: function(response) { $('input:hidden[name="something"]').val(response); }, complete: function() { window.AJAX_CURRENTLY_RUNNING_ON_PAGE = false; } }); }); $('form#find-users').on('submit', function() { if(window.AJAX_CURRENTLY_RUNNING_ON_PAGE) { return; } //dostuff }); 

我在这种情况下可以做的就是使用像块ui这样的插件或者禁用表单提交按钮,原因是你需要在设计中保持交互,你可能能够锁定表单提交,但它更好地给出一个消息或模式灰显