在jQuery中延迟加载动画,同时进行ajax请求

12

我在我的jQuery代码中使用以下模拟来展示加载动画,以显示在进行AJAX请求时:

jQuery.ajaxSetup({
beforeSend: function() {
    $('#loader').show()
},
complete: function(){
    $('#loader').hide()
},
success: function() {
    $('#loader').hide()
}
});

这段代码对我来说完全正常运行!

只有一个问题:

一些请求非常简单且快速,因此加载旋转图标仅显示了几毫秒。当然这不是很美观。

所以我尝试使用setTimeout()稍微延迟显示加载旋转器。我希望它只在AJAX请求需要至少100毫秒时才弹出,但它没有起作用。

因此,我需要一些代码来延迟加载旋转器,如上所述,因此它只在执行“更长时间”的AJAX请求时弹出!


当你说“但它没有起作用”时,是什么没有起作用?你能给我们展示一下你尝试过的代码吗? - jessegavin
6个回答

11

这是我解决你提到的功能的方法。

    var loading;
    $("#loader").hide();
    jQuery.ajaxSetup({
        beforeSend: function() {
             loading= setTimeout("$('#loader').show()", 300);
        },
        complete: function(){
             clearTimeout(loading);
             $("#loader").hide();   
        },
        success: function() {
             alert("done");
        }
    });

如果请求需要301毫秒才能完成,那么这将呈现相同的问题。除了更糟糕,因为现在用户必须等待一段时间,似乎什么都没有发生,然后才会显示。 - Mike Ruhlin
我认为这有点偏好。如果你不知道你的请求需要多长时间,我认为最安全的做法是:在请求超过快速加载阈值之前,暂停显示加载器。 - r0m4n
工作效果不达标!:(问题是在第一次加载页面时,加载旋转器也会显示出来,之后就不会消失了。我尝试在document.ready中使用$('#loader').hide(),但仍然无法在成功加载页面后消失! - Patrick DaVader
最初,如果您在加载时将其隐藏,则没有理由让旋转器可见。所有后续的ajax调用都应使用定义的选项。也许您还有更多要包括的内容? - r0m4n
2
如果您同时有多个 AJAX 调用,这种方法就行不通了,对吧?您知道如何最好地规避这个问题吗? - emrass
2
对于许多ajax请求/回调,我可能会使用jQuery.Deferred()进行管理。http://api.jquery.com/category/deferred-object/ - r0m4n

3
这是一个古老的问题,但我发现了一种更加美观和优雅的方法。jQuery暴露了一个变量$.active,它是当前活动ajax请求的数量。这个值在ajaxSend之前增加,在ajaxComplete之后减少。
有了这个想法,我们所要做的就是在ajaxSend被触发时,$.active == '1'时显示旋转图标,当ajaxComplete被触发时,$.active == '1'时隐藏旋转图标。这是我的代码,目前表现完美。
$(document).ajaxSend(function(event, request, settings) {
    $.active == '1' ? $('#spinner').show() : '';
});

$(document).ajaxComplete(function(event, request, settings) {
    $.active == '1' ? $('#spinner').hide() : '';
});

希望这能帮助到某些人。

0

我看到的常见解决方案是,即使请求比这个时间更快地完成,也要将 throbber 保持一两秒钟。类似于:

var loaded = false;
var throbbed = false;

function checkComplete(){
    if(loaded && throbbed){
        $("#loader").hide();
    }
}

function requestComplete(){
    loaded = true;
    checkComplete();
}

jQuery.ajaxSetup({
beforeSend: function() {
    $('#loader').show();
    setTimeout(function(){
        throbbed = true;
        checkComplete();
    }, 500);

},
complete: requestComplete,
success: requestComplete
});

显然,这样做会以牺牲速度为代价来美化界面,因此是否采用这种方法取决于具体情况。如果是经常使用的功能,最好接受丑陋的界面。如果只是偶尔使用,用户不会注意到额外的500毫秒。

0

这应该可以工作:

var timeout;

jQuery.ajaxSetup({
beforeSend: function() {
    timeout = window.setTimeout(function() {
        timeout = null;
        $('#loader').show();
    }, 100);
},
complete: function(){
    if (timeout) {
        window.clearTimeout(timeout);
        timeout = null;
    }
    $('#loader').hide()
},
success: function() {
    // No need to do anything here since complete always will be called
}
});

如果您同时发送多个请求,现在需要稍微改进一下,但希望您能明白。


工作效果不达标!:(问题是在第一次加载页面时,加载旋转器也会显示出来,之后就不会消失了。我尝试在document.ready中使用$('#loader').hide(),但仍然无法在成功加载页面后消失! - Patrick DaVader

0

现在回复,因为我遇到了同样的问题,这些答案给了我部分解决方案。 为了避免在ajax请求完成后启动spinner,因为超时时间比执行脚本更长,你需要进行一个上/下标志检查,这很简单,对我很有效。

var m = $('.modal-ajax');
var run = false; // global scope is necessary
m.hide(); // if isn't hidden in css

jQuery.ajaxSetup({
    beforeSend: function() {
        run = true; // up flag          
        d = setTimeout(function(){
            if(run) // is ajax executing now?
                m.show();
        },100); // is trigged only for NO fast response
    },
    complete: function(){
        m.hide();
        run = false; // down flag                
    },
    success: function() {            
  //  do stuff
    }
});

0
晚来一步,但希望这对你有所帮助。在我的应用中,使用的是Bootstrap v4.4.1。我定义了一个模态旋转器,如下所示:
<div class="modal-spinner modal fade" id="loadingModal" tabindex="-1" role="dialog" style="display:none;">
        <div class="modal-dialog modal-dialog-centered justify-content-center" role="document">
            <div role="status" style="width: 48px">
                <span class="fa-solid fa-spinner fa-spin fa-4x"></span>
            </div>
        </div>
    </div>

我注意到的是,初始DIV中的“fade”类会导致模态框在快速运行过程中不会消失,正如原帖作者所指出的那样。可以将Bootstrap淡入淡出类改为较短的转换时间,但这对我来说并不总是有效。.ajaxSend、.ajaxComplete和.ajaxStop的组合也不一致。唯一一致的是删除淡入淡出类。
希望能有所帮助.....

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