jQuery:仅当页面上当前没有运行AJAX时才提交表单
当城市输入字段模糊时,我通过ajax请求得到somnething,并将其设置为与城市字段所在的相同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. }); }); });
-
当我们刚刚开始时,我们将
ajaxDefer
对象设置为已解析状态。 这意味着使用.always()
附加的任何函数都会立即执行。 -
当第一个Ajax调用开始时,我们将旧的
ajaxDefer
对象替换为尚未解析的新对象。 使用ajaxDefer.always()
附加的任何新函数将推迟到以后。 -
当最后一个Ajax调用完成时,我们调用
ajaxDefer.resolve()
,这会导致执行任何未执行的延迟函数。 现在我们回到初始状态,任何新附加的函数将立即执行。 -
当有人试图提交表单时,创建一个匿名函数来完成工作并将其附加到
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这样的插件或者禁用表单提交按钮,原因是你需要在设计中保持交互,你可能能够锁定表单提交,但它更好地给出一个消息或模式灰显