我正在尝试使用jQuery在慢速操作期间显示一个小的加载图像,并且无法正确使用它。 这是一张有数千行的大表。当我选中“mostrarArticulosDeReferencia”复选框时,它会从这些行中删除“隐藏”类。此操作需要几秒钟,我想提供一些反馈。 “loading”是一个带有小动画gif的div
这是完整的代码
jQuery(document).ready(function() {
jQuery("#mostrarArticulosDeReferencia").click(function(event){
if( jQuery("#mostrarArticulosDeReferencia").attr("checked") ) {
jQuery("#loading").show(); //not showing
jQuery("#listadoArticulos tr.r").removeClass("hidden"); //slow operation
jQuery("#loading").hide();
} else {
jQuery("#loading").show(); //not showing
jQuery("#listadoArticulos tr.r").addClass("hidden"); //slow operation
jQuery("#loading").hide();
}
});
jQuery("#loading").hide();
});
看起来jquery正在“优化”那3行
jQuery("#loading").show(); //not showing
jQuery("#listadoArticulos tr.r").removeClass("hidden");
jQuery("#loading").hide();
永远不会显示加载div。 任何想法?
奖励:有一种更快的方式来做这个表演/隐藏的事情吗?发现切换速度慢了。
更新: 我试过这个
jQuery("#mostrarArticulosDeReferencia").click(function(event){
if( jQuery("#mostrarArticulosDeReferencia").attr("checked") ) {
jQuery("#loading").show(); //not showing
jQuery("#listadoArticulos tr.r").removeClass("hidden"); //slow operation
setTimeout("jQuery('#loading').hide()", 1000);
} else {
jQuery("#loading").show(); //not showing
jQuery("#listadoArticulos tr.r").addClass("hidden"); //slow operation
setTimeout("jQuery('#loading').hide()", 1000);
}
});
这就是我得到的
更新2: 我有一个有效的解决方案。但为什么我必须使用setTimeout来使它工作超出我的范围......
jQuery("#mostrarArticulosDeReferencia").click(function(event){
if( jQuery("#mostrarArticulosDeReferencia").attr("checked") ) {
jQuery("#loading").show();
setTimeout("jQuery('#listadoArticulos tr.r').removeClass('hidden');", 1);
setTimeout("jQuery('#loading').hide()", 1);
} else {
jQuery("#loading").show();
setTimeout("jQuery('#listadoArticulos tr.r').addClass('hidden');", 1);
setTimeout("jQuery('#loading').hide()", 1);
}
});
更新3: 刚为这个特殊情况找到了更好的解决方案。
//mostrar u ocultar articulos de referencia
$("#mostrarArticulosDeReferencia").click(function(event){
if( $("#mostrarArticulosDeReferencia").attr("checked") )
$("tr.r").css({'display':'table-row'});
else
$("tr.r").css({'display':'none'});
});
使用.css({'display':'none'})比hide()更快,所以不需要加载动画...
这篇文章向我展示了光:show/hide performance。
答案 0 :(得分:3)
我尝试了一切,我必须得出结论,这是浏览器脑力的产物。
'setTimeout'强制浏览器以正确的顺序执行所有步骤。 它很糟糕,不优雅,但至少它有效......
更新:setTimeout是必需的,因为jquery“简化”了命令链。如果我告诉它隐藏一个元素并再次显示它,它将简单地忽略该命令,因为最终结果将是什么都不做......
答案 1 :(得分:3)
显然你在“长”期间发出异步请求(是的,异步,换句话说,它不会与代码同步!)运行过程“。您需要在异步请求的回调函数结束时调用$('#loading').hide()
。
这是一个很好的例子:
$('#loading').show();
$.getJSON('someURL', function(data) {
// Do slow processing.
});
$('#loading').hide();
这显然不会起作用。它将显示,触发异步请求然后立即隐藏。您需要将代码重写为:
$('#loading').show();
$.getJSON('someURL', function(data) {
// Do slow processing.
$('#loading').hide();
});
答案 2 :(得分:1)
我想你想要做
jQuery("#listadoArticulos tr.r").removeClass("hidden");
在show的回调函数中。
请查看此处的方法文档:http://docs.jquery.com/Effects/show
通过调用show(0);
但你想做回调吗?没问题,这样做:
show(0, function() { jQuery("#listadoArticulos tr.r").removeClass("hidden"); });
简单! :)
答案 3 :(得分:1)
只是一个注释 - 我已经开发了一个plugin来创建一个带有加载图形的叠加div。
答案 4 :(得分:1)
在页面上放置一个div,如下所示:
<div id="spinner" class="spinner" style="display:none;">
<img id="img-spinner" src="@Url.Content("~/images/loading.gif")" alt="Loading"/>
</div>
然后挂钩show并隐藏到ajaxStart,ajaxStop和ajaxError事件,如下所示:
$("#spinner").bind("ajaxSend", function() { $(this).show(); })
$("#spinner").bind("ajaxStop", function() { $(this).hide(); })
$("#spinner").bind("ajaxError", function() { $(this).hide(); });
答案 5 :(得分:0)
您是否尝试过使用ajaxStart来运行更新功能?
答案 6 :(得分:0)
我认为它运作正常。这个操作:
jQuery("#listadoArticulos tr.r").removeClass("hidden");
实际上并不是那么慢,而是在几毫秒的时间内执行,所以你看不到加载信息,因为它只是在那里很短的时间。
答案 7 :(得分:0)
我也看到了这种行为,这取决于所使用的浏览器。 IE是受影响最大的一个。原因不是jQuery很慢,虽然JavaScript在IE中运行较慢,但更多是由于新HTML的呈现。 setTimeout()帮助的原因是因为它执行第一个操作,并且只有在浏览器完成后才渲染新HTML,第二部分完成。整个操作实际上较慢,但反馈使其更好。
证明这一点的一种方法是隐藏长表并运行相同的代码。它会做同样的事情,但因为表是不可见的,并且不会使整个动作更快。
有几种方法可以解决这个问题。
答案 8 :(得分:0)
这不回答原始问题,但是对表格本身的类使用CSS规则是否更快:
#listadoArticulos.hideCertainRows tr.r { display: none }
并按如下方式切换显示:
jQuery("#listadoArticulos").addClass("hideCertainRows");
答案 9 :(得分:0)
尝试使用show方法的回调“完成”,js主要基于异步事件,这三行:
jQuery("#loading").show(); //not showing
jQuery("#listadoArticulos tr.r").removeClass("hidden");
jQuery("#loading").hide();
将在没有等待的情况下执行,所以,你的显示,添加类并立即隐藏div,这就是为什么你看不到div,你隐藏它而不等待被显示它出现并且真的消失了快速,甚至可能永远不会出现(不知道该类型的任何优化)。
如果你在完整的回调中添加最后两个它将起作用,更多http://api.jquery.com/show/:
jQuery("#loading").show(400, function (){
jQuery("#listadoArticulos tr.r").removeClass("hidden");
jQuery("#loading").hide();
});
在任何情况下,对ajax请求执行此操作的正确方法(我认为对某人有用)正在使用ajaxStart和ajaxStop,如下所示:
$(document).ajaxStart(function() {
$( "#loading" ).show();
}).ajaxStop(function() {
$( "#loading" ).hide();
});
添加removeClass缺少回调:
也许你的问题在于removeClass没有回调,但你可以做下一个:
jQuery("#loading").show(400, function (){
var els = jQuery("#listadoArticulos tr.r");
els.each(function(i, el) {
el.removeClass("hidden");
if (els.length == i +1) jQuery("#loading").hide();
});
});
试试这个:
var els = jQuery("#listadoArticulos tr.r");
els.each(function(i, el) {
if (i == 0) jQuery("#loading").show();
el.removeClass("hidden");
if (els.length == i +1) jQuery("#loading").hide();
});
你可以添加一个问题,如果你有图像或任何额外的代码,一旦你删除类激活,没有本机方式等待他们隐藏加载div,所以即使你删除隐藏在那里的类等待物体可见是不容易的。
我只是注意到这是2年前,也许你不再需要它了。