I’m trying to show a small loading image during a slow operation with jQuery and can’t get it right.
It’s a BIG table with thousands of rows. When I check the “mostrarArticulosDeReferencia” checkbox it removes the “hidden” class from these rows. This operation takes a couple of seconds and I want to give some feedback.
“loading” is a div with a small animated gif
Here’s the full code
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();
});
It looks like jquery is “optimizing” those 3 lines
jQuery("#loading").show(); //not showing
jQuery("#listadoArticulos tr.r").removeClass("hidden");
jQuery("#loading").hide();
And never shows the loading div.
Any Ideas?
Bonus: There is a faster way of doing this show/hide thing? Found out that toggle is WAY slower.
UPDATE:
I tried this
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);
}
});
That’s what I get
- click on checkbox
- nothing happens during 2/3 secs (processing)
- page gets updated
- loading div shows up during a split second
UPDATE 2:
I’ve got a working solution. But WHY I have to use setTimeout to make it work is beyond me…
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);
}
});
UPDATE 3:
Just found a better solution for this particular case.
//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'});
});
Using .css({‘display’:’none’}) turns out to be WAY faster than hide(), so no need for the loading animation…
This article showed me the light: show/hide performance.
I tried everything and I have to conclude than this is the product of a browser brainfart.
‘setTimeout’ in my last update is forcing the browser tho execute all the steps in the correct order.
It sucks, isn’t elegant, but at least it works…
Update: the setTimeout is necessary because jquery “simplifies” the chain of commands. If I tell it to hide one element and the show it again, it will simply ignore the command because the final result will be the same as do nothing…