我在页面上有几个AJAX调用。有些完成,其他人需要一些时间 - 所有这些都取决于点击的内容。
我想添加一个“加载器”,在AJAX处理结果的X秒后显示。
我有一台装载机在工作:
$(document).ajaxStart(function() {
$("#loader").css("display","block");
}).ajaxSuccess(function() {
$("#loader").css("display","none");
});
这个功能。
但是,当AJAX请求很快时,它会在屏幕上闪烁 ...就像在眨眼间一样。除了发生“闪烁”之外,它效果很好。因此,我试图将加载程序css更改延迟几秒钟,以便快速结果不会导致“闪烁”。
我试图使用setTimeout和jQuery队列来延迟事情...... a la:
$(document).ajaxStart(function() {
$("#loader").queue(function(){
$(this).delay(5000);
$(this).css("display","block");
$(this).dequeue();
});
}).ajaxSuccess(function() {
$("#loader").css("display","none");
});
或:
$(document).ajaxStart(function() {
setTimeout(function() {
$("#loader").css("display","block");
}, 5000);
}).ajaxSuccess(function() {
$("#loader").css("display","none");
});
<子>(delaying jquery css changes)子>
或:
$(document).ajaxStart(function() {
$("#loader").delay(5000).css("display","block")
}).ajaxSuccess(function() {
$("#loader").css("display","none");
});
但我遇到的问题是,任何延迟cj更改的尝试都会导致延迟... 然后负载出现(在ajax完成之后)。
所以页面加载AJAX数据然后5秒钟......加载器出现。
有没有一种好方法告诉ajaxstart()函数在执行前等待X秒?
我不一定想使用像onBefore函数()之类的东西来实现这部分实际的ajax调用,主要是因为某些结果很快返回并且不需要任何进度指示器。通常情况下,进展应不显示。 大多数 ajax请求在5秒内完成,只有少数可能需要10-20秒。
我已经将'loader'的删除添加到ajax调用中的complete function()中。只是为了确定加载器在ajax完成时消失了。但是如果在达到任何setTimeout()值之前ajax完成,那么这也会失败(然后在不应该加载时出现加载器)。
如果ajax花费X秒或更长时间,我只想要对元素进行css更改...可以这样做吗?
有没有办法在AJAX请求中计时?
答案 0 :(得分:8)
setTimeout()
有nice feature,您可以在此处获得对超时的引用并取消它。
var ajaxLoadTimeout;
$(document).ajaxStart(function() {
ajaxLoadTimeout = setTimeout(function() {
$("#loader").css("display","block");
}, 5000);
}).ajaxSuccess(function() {
clearTimeout(ajaxLoadTimeout);
$("#loader").css("display","none");
});
这可以防止超时被触发,而不是等待它,如果已经调用完成则无所事事(如雅各布的答案)。
答案 1 :(得分:4)
在显示#loader
:
var ajaxDone; //create a global variable called ajaxDone
$(document).ajaxStart(function() {
ajaxDone = false; //by default, set the ajax as not completed each time the ajax request is sent
setTimeout(function() {
if(!ajaxDone) $("#loader").css("display","block");//checks if the ajax has finished yet before displaying #loader
}, 5000);
}).ajaxSuccess(function() {
ajaxDone=true;//When the ajax request finishes, it sets ajaxDone to true
$("#loader").css("display","none");
});
答案 2 :(得分:1)
对于我能够找到解决方案的好答案。
我最终想要本地化&#34; loading&#34;要基于元素ID显示的图像。全局ajaxStart()
和ajaxComplete()
功能不会处理本地事件。所以我用超时切换到beforeSend()
函数:
$('.item').click( function (e) {
e.preventDefault();
var theID = $(this).attr('data');
var theInfo = $('.holder#h' + theID);
var loader = $('.waiting#w' + theID);
$('.holder').slideUp(); //closes any open data holders
var ajaxLoadTimeout;
if (!$(theInfo).hasClass('opened')) {
$(this).addClass('clicked');
$(theInfo).addClass('opened');
$(theInfo).html(''); //removes any existing data
$.ajax({
url: '_core/inc/getdata.php',
type: 'POST',
data: ({dataid: theID}),
dataType: 'html',
//shows LOCAL loader before ajax is sent
//but waits 3 milliseconds before doing so
//most of the ajax calls take less than 3ms
//without the timeOut the loader "flashes" for a milisecond
beforeSend : function() {
ajaxLoadTimeout = setTimeout(function() {
$(loader).show();
}, 300);
},
success: function(data) {
$(theInfo).html(data);
//Hides LOCAL loader upon ajax success
clearTimeout(ajaxLoadTimeout);
$(loader).hide();
},
complete: function(){
$(theinfo).slideDown();
}
});
} else {
$(this).removeClass('clicked');
$(theInfo).removeClass('opened').slideUp();
}
});
相关的PHP / HTML:
echo '
<h1 class="item" data="'.$this_id.'">'.$this_title.' <span class="waiting" id="w'.$this_id.'"><i class="fa fa-refresh fa-spin fa-lg"></i></span></h1>
<section class="holder" id="h'.$this_id.'"></section>';
CSS:.waiting { discplay: none; }
我不知道这是对还是错,但似乎在这里按预期工作。
如果该项目的加载时间超过几毫秒,它允许字体真棒图标出现在项目标题旁边。