2009-08-10 51 views
7

我试图在jQuery的慢速操作过程中显示一个小的加载图像,但无法正确显示。 这是一张有数千行的大表格。当我检查“mostrarArticulosDeReferencia”复选框时,它会从这些行中删除“隐藏”类。这个操作需要几秒钟,我想给出一些反馈。 “加载”是用小gif动画jQuery在缓慢的操作过程中显示“加载”

这里一个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是“优化”的三线

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

这就是我得到

  1. 点击复选框
  2. 没有在2/3秒(处理)
  3. 网页被更新
  4. 发生
  5. 加载div在瞬间显示

更新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({“显示”:“无”})原来是WAY不是隐藏()快,因此无需加载动画...
这篇文章给我看光:show/hide performance

+0

你想在加载页面时运行它吗? $(document).ready()在所有内容都被关闭并加载时触发 – AutomatedTester 2009-08-10 06:42:59

+0

不需要,我只在显示/隐藏操作期间需要这个。 刚刚粘贴了整个脚本 – 2009-08-10 06:46:05

+1

只是一个想法,你有尝试过使用上下文吗?如果您在选择器语句中提供第二个参数,这可以帮助加速。 – 2009-08-10 08:21:23

回答

2

我试了一切,我不得不得出结论,这是浏览器brainfart的产品。

  1. 的jQuery告诉浏览器显示/隐藏加载DIV
  2. 的jQuery告诉浏览器添加从行
  3. 的jQuery告诉浏览器/删除隐藏类显示/隐藏加载DIV
  4. 浏览器就以错误的顺序(2排在首位)所有上述步骤

“setTimeout的”在我的最后一次更新是迫使浏览器执行寿按照正确的顺序中的所有步骤。 它吮吸,不是优雅,但至少它的作品...

更新:setTimeout是必要的,因为jquery“简化”的命令链。如果我告诉它隐藏一个元素并再次显示它,它将简单地忽略该命令,因为最终结果将与无所作为相同。

+0

我想我添加了一条评论,说这个答案误导了正确的答案,并且没有来自浏览器部分的brainfart,它来自jquery库,并且它对removeClass回调没有回调(它看起来像自然)。我不知道为什么它被删除。 – 2013-02-04 07:50:34

0

您是否试过使用ajaxStart来运行您的更新功能?

+0

你会如何使用它?无法得到它的工作 – 2009-08-10 07:22:31

+0

检查此问题:http://stackoverflow.com/questions/1191485/how-to-call-ajaxstart-on-specific-ajax-calls – Jason 2009-08-10 07:28:17

0

我认为它工作正常。此操作:

jQuery("#listadoArticulos tr.r").removeClass("hidden"); 

是不是真的那么慢,它在几毫秒顶部进行,所以你看不到的加载信息,因为它只是在那里很短的时间。

+0

我有几行,它需要2或3秒。这是非常讨厌的 – 2009-08-10 06:50:39

+0

如果你注释掉隐藏和删除类指令,你会看到加载div吗? – RaYell 2009-08-10 07:21:18

+0

就像你说的那样? \t的jQuery( “#mostrarArticulosDeReferencia”)。点击(函数(事件){ \t \t如果(jQuery的( “#mostrarArticulosDeReferencia”)。ATTR( “选中”)){ \t \t \t \t的jQuery( “#加载” ).show(); //未示出 \t \t \t \t // jQuery的( “#listadoArticulos tr.r”)removeClass( “隐藏”); //慢的操作 \t \t \t \t // jQuery的(“#加载“)。hide(); \t \t} else { \t \t \t \t jQuery(“#loading”)。show(); //不显示 \t \t \t \t // jQuery(“#listadoArticulul tr.r”)。addClass(“hidden”); //运行缓慢 \t \t \t \t // jQuery(“#loading”)。hide(); \t \t} \t}); 是的,我看到加载div,但我后来隐藏它的书呆子... – 2009-08-10 07:29:36

1

我想你想要做

jQuery("#listadoArticulos tr.r").removeClass("hidden"); 

作秀的回调函数内。

看看这个方法的文档在这里:http://docs.jquery.com/Effects/show

可以实现通过调用show(0);

相同的“即时显示”效果,但是你想做的回调?没问题,这样做:

show(0, function() { jQuery("#listadoArticulos tr.r").removeClass("hidden"); }); 

简单! :)

+0

这样做我得到了和以前一样的行为 1.点击复选框 2.在2/3秒内没有任何反应(处理) 3。页面得到更新 4.加载div在分秒显示 而且我必须使用settimeout来隐藏div。如果我不使用它,该div永远不会显示... – 2009-08-10 08:57:21

+0

你有没有一个我可以玩的现场例子?我在考虑改变每一行,如果你有一整套,你可以改变tbody标签。 – 2009-08-10 09:48:08

0

我也看到了这种行为,这取决于使用的浏览器。 IE是受影响最大的一个。原因不是jQuery很慢,尽管JavaScript在IE中运行速度较慢,但​​更多的是由于新HTML的呈现。 setTimeout()帮助的原因是因为它执行了第一个操作,并且只有在浏览器完成呈现新的HTML时才完成第二部分。整个操作实际上比较慢,但反馈使它更好。

演示这一点的一种方法是隐藏长表并运行相同的代码。它会做同样的事情,但由于表格是隐形的,并且不会使整个动作更快。

有几种方法可以解决这个问题。

  1. 尽量避免使用表格并改为使用DIV布局。表格渲染速度慢,并且根据浏览器的不同,表格可能只能被看到然后完全渲染。
  2. 如果您必须使用表格,请考虑使用多个粘贴在一起的100行表格。这样一旦第一张表格被重新格式化,页面就开始渲染。
  3. 如果只有一个大表是唯一的出路,而且您知道用户只能看到顶部的行,您可以两次执行操作,第一次在顶部行中,第二次在所有行上执行。这是最慢和最不理想的解决方案,但可以通过向操作添加jQuery筛选器来实现,非常容易。
+1

你为什么推荐表格数据的div?你为什么建议分解数据?你关心语义吗? – 2009-08-10 08:25:57

+1

或可访问性? – 2009-08-10 08:26:33

+0

主要是因为浏览器中表格的渲染速度。使用div和css是一个很好的选择。当然,也可以选择使用固定的桌面布局,这也会有所帮助。请参阅:http://stackoverflow.com/questions/1046035/why-is-ie7-so-slow-compared-to-safari。 – Maurice 2009-08-10 08:35:06

0

这不回答原来的问题,但它是任何更快地对表本身使用CSS规则的一类:

#listadoArticulos.hideCertainRows tr.r { display: none } 

和切换这样的显示:

jQuery("#listadoArticulos").addClass("hideCertainRows"); 

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(); 
}); 
+0

有时很简单的事情就是答案。感谢BalusC的例子。 – Chris 2013-12-03 19:03:37

1

刚一说明 - 我已经开发了plugin创建与它装载图形叠加股利。

1

把一个div您的网页上的某个地方,像这样:

<div id="spinner" class="spinner" style="display:none;"> 
    <img id="img-spinner" src="@Url.Content("~/images/loading.gif")" alt="Loading"/> 
</div> 

然后勾显示和隐藏于ajaxStart,ajaxStop和ajaxError事件,像这样:

$("#spinner").bind("ajaxSend", function() { $(this).show(); }) 
$("#spinner").bind("ajaxStop", function() { $(this).hide(); }) 
$("#spinner").bind("ajaxError", function() { $(this).hide(); }); 
0

尝试使用回调“完整”的展示方法,js大部分基于异步事件,并且这三行:

jQuery("#loading").show(); //not showing 
jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
jQuery("#loading").hide(); 

是g无需等待即可执行,因此,您的演出,添加课程并立即隐藏div,这就是为什么您无法看到div的原因,您无需等待即可隐藏它,并且它看起来很快,甚至消失得非常快,甚至它可能永远不会显示(不知道该类型的任何优化)。

如果在完整的回调中添加最后两个,它将起作用,更多http://api.jquery。COM /显示/:

jQuery("#loading").show(400, function(){ 
    jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
    jQuery("#loading").hide(); 
}); 

在任何情况下,也在为Ajax请求,这样做的正确方法(我想象将是有用的人)使用ajaxStartajaxStop这样的:

$(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年前,也许你不需要这个了。