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

TK1*_*123 3 javascript ajax jquery

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

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

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

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

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

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

编辑

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

sla*_*pon 12

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

$(document).ready(function() {
    var ajaxBusy = false;

    $(document).ajaxStart( function() { 
        ajaxBusy = true; 
    }).ajaxStop( function() {
        ajaxBusy = false;
    });
});
Run Code Online (Sandbox Code Playgroud)

编辑:

所以这回答了你直接的问题:"如何知道是否有任何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);
    });
});
Run Code Online (Sandbox Code Playgroud)

编辑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.
        });
    });
});
Run Code Online (Sandbox Code Playgroud)
  1. 当我们刚刚开始时,我们将ajaxDefer对象设置为已解决状态.这意味着使用附加的任何函数.always()将立即执行.

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

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

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