2012-07-10 47 views
5

tengo un código que funciona bien, pero se ha convertido en demasiado lento:jQuery: contar los elementos visibles - eficiencia/problemas de velocidad

HTML:

tengo un recipiente que contiene alrededor de 50 ul elementos. Cada elemento ul tiene un encabezado h4 seguido de una serie de elementos li. La función oculta el encabezado si no hay elementos de línea visibles.

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

Estaba funcionando bastante aceptablemente hasta que cambió la naturaleza de los elementos li. Cada li ahora es una mini tabla que comprende <table><tr><td>icon</td><td>text</td></tr></table>. Ahora lleva 2 segundos procesar, mientras que antes funcionaba en menos de medio segundo. (La tabla está ahí para detener el ajuste del texto debajo del ícono).

Confieso que no entiendo muy bien por qué agregar los elementos adicionales en cada li debería ralentizar tanto el procesamiento de DOM porque utilicé el .children selector para solo ir una capa DOM profunda.

También he intentado:

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

y $('#container').children().children('h4') una buena medida.

Lo que es notable, también, es que cuando hay muchos elementos li visibles, es mucho más lento que cuando son pocos visibles. Sin embargo, ahora no hay más líneas que cuando funcionó con bastante rapidez (es decir, antes de colocar la tabla en cada línea).

Cualquier consejo muy apreciada, pero por favor no solicitar he puesto más código que tengo :)

Gracias.

+1

Necesita publicar un ejemplo del marcado relacionado, por lo que ha dicho, tiene problemas. A [UL] (http://www.w3.org/TR/html5/the-ul-element.html#the-ul-element) ** solo ** puede tener elementos secundarios LI, el H4 está siendo error- corregido para que no tenga la estructura que cree que tiene. Además, la tabla para formatear el contenido de LI no es necesaria, use CSS. Ah, y un H4 no puede tener LI como nodos secundarios, deben tener un padre UL u OL. – RobG

+0

¿Qué hay de nowrap en lugar de mesa? Además, ¿por qué no ocultar el padre h4 cuando oculta a los niños en lugar de al revés? – mplungjan

+0

OK, gracias. Revisaré el marcado y volveré a este. – Nick

Respuesta

2

Sospecho que determinar si un elemento es visible o no es bastante caro. Considere en su lugar agregar y eliminar una clase para ocultar o mostrar elementos. A continuación, puede seleccionarlos directamente en función de la clase, que en su mayoría será compatible con un host getElementsByClassName o querySelectorAll método.

+0

¡Esta es la base del desastre en el que estoy! Yo * estoy * escondiéndome y mostrando cosas por varias clases, pero ahora necesito determinar si algo todavía se muestra :) La otra cosa es que no fue tan caro hasta que puse la mesa en la línea. Ese es el enigma real. Puedo quitar la mesa y funciona bien. – Nick

+0

He marcado la respuesta en reconocimiento de los buenos consejos aquí y en el comentario anterior, aunque nadie ha respondido realmente la pregunta como lo pregunté :) He eliminado la tabla y reformateado el marcado que funciona alrededor del problema multa. – Nick

2

intento:

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

pero estoy de acuerdo con RobG, you'r marcado es probablemente incorrecta.

Cuestiones relacionadas