JQuery: counting visible elements - performance / speed issues

I have code that works fine, but it gets too slow:

HTML:

I have a container containing about 50 ul elements. Each ul element has a h4 heading followed by a series of li elements. The function hides the title if there are no visible line elements.

Javascript / jQuery:

  function show_or_hide_headings() { $('#container').children('ul').each(function (i) { var $this = $(this), $h4 = $this.children(':first'); if ($this.children('li:visible').length) { $h4.show(); } else { $h4.hide(); } }); } 

It worked pretty well until I changed the nature of the li elements. Each li now represents a mini-table containing <table><tr><td>icon</td><td>text</td></tr></table> . It takes 2 seconds to process, whereas before it worked in less than half a second. (The table is designed to stop the flow of text under the icon.)

I admit, I can’t understand why adding additional elements to each li should slow down the DOM processing so much that I used the .children selector .children that only one DOM layer is deep.

I also tried:

  $('#container').find('h4').each(function (i) { var $this = $(this); if ($this.siblings('li:visible').length) { $this.show(); } else { $this.hide(); } }); 

and $('#container').children().children('h4') for good measure.

It is also noteworthy that when there are many li elements, it is much slower than when few are visible. However, there are no more rows than when they worked pretty fast (i.e. before the table was placed on each row).

Any advice is greatly appreciated, but please do not ask to send more code than me :)

Thank.

+5
javascript jquery children visible
Jul 10 '12 at 5:11
source share
2 answers

I suspect that determining whether an element is visible or not is quite expensive. Instead, add and remove a class to hide or show items. Then you can select them directly based on the class, which will be mainly supported by the getElementsByClassName host or by the querySelectorAll method.

+2
Jul 10 2018-12-12T00:
source share

to try:

 $('h4', '#container').css('display', 'none').filter(function() { return $(this).siblings('li:visible').length; }).css('display', 'block'); 

but I agree with RobG, your markup is probably incorrect.

+2
Jul 10 2018-12-12T00:
source share



All Articles