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

时间:2012-10-31 19:30:55

标签: javascript jquery ajax

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

$('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完成然后提交。

5 个答案:

答案 0 :(得分:11)

使用jQuery的Ajax Events。只要使用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请求。注意你的关闭。

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

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

类似

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;
    }
    });
});

答案 3 :(得分:1)

使用你建议的锁定变量:

$('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
});

答案 4 :(得分:0)

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