禁用特定请求的ajaxStart()和ajaxStop()函数

83

我正在使用 .ajaxStart() 和 .ajaxStop() 函数来在 ajax 请求期间(开始和结束之间)显示一个模态框。

现在,我想添加一个长轮询函数,以类似于此网站左上角的通知一样等待通知。

现在我的问题在于仅针对长轮询请求禁用此模态框。

注册“加载屏幕”开关处理程序:

$(document).ajaxStart(handleAjaxStart);
$(document).ajaxStop(handleAjaxStop);

我的长轮询函数:

$.ajax({
    timeout: 35000,
    url: longPollUrl,
    success: function(data){
        if(data.queCount) $('#numQueCount').html(data.queCount);
        if(data.queAccept) $('#numQueAccept').html(data.queAccept);
    }, 
    dataType: 'json',
    complete: longpoll
});

我尝试了:

$().off('ajaxStart');
$().off('ajaxStop');

我尝试在开始轮询后重新附加处理程序,但没有成功。

我还尝试在handleAjaxStart()中引入一个全局变量,在函数的第一行返回,但似乎完全消除了加载屏幕。

有什么想法可以实现这个功能吗?

2个回答

206

我明白了。

.ajax() 函数的选项对象中有一个叫做 global 的属性。

如果将其设置为 false,则不会触发该调用的 ajaxStart 事件。

$.ajax({
    timeout: 35000,
    url: longPollUrl,
    success: function(data){
        if(data.queCount) $('#numQueCount').html(data.queCount);
        if(data.queAccept) $('#numQueAccept').html(data.queAccept);
    }, 
    global: false,     // this makes sure ajaxStart is not triggered
    dataType: 'json',
    complete: longpoll
});

4
很高兴他们考虑到了这种情况,即我们需要绕过那些捕获所有ajax函数的方法。将global设置为false将禁止所有全局触发器:ajaxComplete()ajaxError()ajaxSend()ajaxStart()ajaxStop()ajaxSuccess(),而不仅仅是Start和Stop。 - XstiX
不错的发现!jQuery 能够预先防范这种情况,想得真好。 - Joshua Pinter

18

阅读完所有可能的解决方案后,我想要将答案结合起来。

解决方案1:Bind/Unbind

//binding
$(document).bind("ajaxStart.mine", function() {
    $('#ajaxProgress').show();
});

$(document).bind("ajaxStop.mine", function() {
    $('#ajaxProgress').hide();
});

//Unbinding
$(document).unbind(".mine");

这是一个已弃用的解决方案。在 jQuery 1.9 之前,可以将像 ajaxStart、ajaxStop、ajaxError 等全局 ajax 事件绑定到任何元素上。自 jQuery 1.9 后:

自 jQuery 1.9 起,jQuery 全局 Ajax 事件的所有处理程序(包括使用 .ajaxStart() 方法添加的处理程序)必须附加到文档上。

因此,我们无法将这些事件绑定/解除绑定到自定义命名空间上。

解决方法 2:将属性 global 设置为 false

$.ajax({
        url: "google.com",
        type: "GET",
        dataType: "json",
        global: false, //This is the key property.
        success: function (data) {
                   console.log(data);
                },
        error: function (data) {
                   console.log(data);
                }
       });

此解决方案用于禁用ajaxStart()/ajaxStop()事件。但它也会禁用ajaxComplete(),ajaxError(),ajaxSend(),ajaxSuccess()。如果您不使用这些全局事件,看起来没问题,但当需要时,您必须返回并更改在其中设置global:false的所有页面的解决方案。

解决方案3:使用全局变量

var showLoadingEnabled = true;
$(document).ready(function () {
    $('#loading')
        .hide()  // at first, just hide it
        .ajaxStart(function () {
            if (showLoadingEnabled) {
                $(this).show();
            }
        })
        .ajaxStop(function () {
            if (showLoadingEnabled) {
                $(this).hide();
            }
        });
});


function justAnotherFunction() {
    window.showLoadingEnabled = false;
    $.ajax({
        url: 'www.google.com',
        type: 'GET',
        complete: function (data) {
            window.showLoadingEnabled = true;
            console.log(data);
        }
    });
}

在 JavaScript 文件中不应使用全局变量。但是这是我能找到的最简单的解决方案。

对于我的项目,我更喜欢第三种解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接