2010-06-29 23 views
6

Tengo una tabla html con alrededor de 30 columnas y entre 10 y 500 filas ish. Me gustaría mostrar/ocultar un conjunto de columnas o hacer clic con el botón.jQuery show/hide column en el rendimiento de la gran tabla

He tratado 2 se aproxima a

  1. iterar a través de la culata en T º de mesa y hacer .show() o .hide() en el TH y TD.
  2. iterar a través de la tabla thad y cambiar la clase para mostrar/ocultar el TH y TD.

la función se implementa como el siguiente fragmento. Sin embargo, el rendimiento no es tan bueno. Mostrar/Ocultar decir 20 columnas toma alrededor de 5 ~ 10 segundos en tal vez 80 ~ 120 filas de datos.

me pregunto si hay algo que podamos hacer para que sea más rápido.

function ToggleHeadVisibility(showHide) { 

    var index = 0; 

    $('#' + gridViewName + ' thead th').each(function(index) { 
     index++; 
     if (showHide == "SHOW") { 
      /* 
      $('#' + gridViewName + ' th:nth-child(' + (index) + ')').show(); 
      $('#' + gridViewName + ' td:nth-child(' + (index) + ')').show(); 
      */ 
      $('#' + gridViewName + ' th:nth-child(' + (index) + ')').removeClass('columnHide'); 
      $('#' + gridViewName + ' td:nth-child(' + (index) + ')').removeClass('columnHide'); 
     } else if (showHide = "HIDE") { 
      /* 
      //if (showColumnArray.has($(this).get(0).innerHTML)) { 
      if (showColumnArray.has($(this).attr('title'))) { 
      $('#' + gridViewName + ' th:nth-child(' + (index) + ')').show(); 
      $('#' + gridViewName + ' td:nth-child(' + (index) + ')').show(); 
      } 
      else { 
      $('#' + gridViewName + ' th:nth-child(' + (index) + ')').hide(); 
      $('#' + gridViewName + ' td:nth-child(' + (index) + ')').hide(); 
      } 
      */ 
      if (showColumnArray.has($(this).attr('title'))) { 
       $('#' + gridViewName + ' th:nth-child(' + (index) + ')').removeClass('columnHide'); 
       $('#' + gridViewName + ' td:nth-child(' + (index) + ')').removeClass('columnHide'); 
      } else { 
       $('#' + gridViewName + ' th:nth-child(' + (index) + ')').addClass('columnHide'); 
       $('#' + gridViewName + ' td:nth-child(' + (index) + ')').addClass('columnHide'); 
      } 

     } 
    }); 
} 
+1

una comparación interesante en el rendimiento de mostrar/ocultar http://www.learningjquery.com/2010/05/now-you-see-me-showhide-performance – Eatdoku

Respuesta

9

Algunas sugerencias:

  1. Aunque la construcción de una tabla, agregar clases css como col1, col2, col3 etc a la cabecera y las celdas de datos. Entonces podría simplemente hacer $("td.col1").hide(); para ocultar la columna respectiva. Es más rápido que el selector n-ésimo hijo.

  2. En IE y Firefox, puede establecer visibility: collapse en un elemento col para contraer toda la columna. Esto será mucho más rápido. Desafortunadamente no es compatible con los navegadores Webkit http://www.quirksmode.org/css/columns.html.Puede ramificar su código basado en el navegador para que sea rápido al menos en IE y Firefox.

  3. Si su tabla tiene un table-layout: fixed, puede mejorar significativamente el rendimiento porque su navegador no tiene que seguir calculando el ancho de las columnas cada vez que toca la tabla como en el modo automático.

  4. Considere eliminar la tabla del árbol DOM (a través de .remove()), realice la operación mostrar/ocultar en bloque e insértela de nuevo. Esta es una regla general siempre que desee realizar operaciones masivas en el árbol DOM.

+0

Tuve el mismo problema que el OP, probablemente con una mesa aún más grande. Lo resolví bastante bien agregando clases en la tabla construida, según el punto 1 anterior, y luego cambiando la definición css de las clases dinámicamente con Javascript, en lugar de usar las clases como selectores para cambiar el estilo CSS en línea. – undefinederror

1

Evidentemente, esta alternativa es un poco más ágil para mostrar y ocultar elementos:

.css({'display':'none'}) & .css({'display':'block'}); 

http://www.learningjquery.com/2010/05/now-you-see-me-showhide-performance

Pero sospecho que su verdadero problema es que bucle.

+0

se realice bien con 20 ~ 40 filas ish. Estoy pensando que el looping de 30ish TH no es realmente un gran problema. Probablemente esté más en el selector "th: nth-child". Hay demasiados de ellos. ¿Tal vez hay otro enfoque? – Eatdoku

0

aquí es la paz de código i utilizado para ocultar la columna "enésimo" en mi rejilla ...

if (true) { 
     $('th:nth-child(' + c + ')').show(); 
     $('td:nth-child(' + c + ')').show();       
    } 
    else { 
     $('th:nth-child(' + c + ')').hide(); 
     $('td:nth-child(' + c + ')').hide();       
    } 

muy similar a la suya, excepto que solía alternar jQuery "mostrar/ocultar";

que parece mostrar la columna/ocultar de 400 filas bajo 1 segundo ...

Borik

+0

Lo probé con jQuery show() y hide() en lugar de agregar/eliminar clases como puede ver en el fragmento de código (el código comentado). el rendimiento es aproximadamente el mismo. – Eatdoku

0

Se podría hacer mucho en el área de almacenamiento en caché. Para empezar, almacenar en caché el contenedor GridView:

var gridView = $('#' + gridViewName); 

y, posteriormente, una fila puede almacenar en caché:

var row[0] = gridView.find('tr:nth-child(0)'); // Not sure the path is right, but you get the idea... 

Asimismo, realice la piel real utilizando el conjunto, en lugar de una each()

row[0].addClass('columnHide'); // Calls addClass() on each element in the set 

El almacenamiento en caché de elementos por adelantado en lugar de consultar repetidamente el DOM con $, y realizar acciones en conjuntos de elementos en lugar de bucles puede recorrer un largo camino en el rendimiento.

0

Iteración a través de las filas y columnas siempre va a ralentizar las cosas. Intente manipular las reglas de CSS directamente para evitar la iteración en su JavaScript y obligue al navegador a hacerlo por usted.

Pagar los complementos jQueryRule y jQueryCSSRule.

La manipulación directa de reglas de CSS puede ser beneficiosa si combina todas las reglas. Aquí hay un quick test con 500 filas y 50 columnas. La mayor parte del tiempo se usa para volver a renderizar, y el tiempo pasado dentro de la función de JavaScript me da un promedio de 200-300 ms en Chrome y 0 ms en Firefox. Actualmente usa API estándar, pero es trivial extender esto a IE.

Funciona mediante la creación de un nuevo nodo <style> dentro del documento, y agregando todas las manipulaciones de columna allí. La idea clave es combinar todas las reglas en una al ocultar ciertas columnas. Así que en lugar de hacer:

table tr :nth-child(1) { display: none; } 
table tr :nth-child(4) { display: none; } 
table tr :nth-child(7) { display: none; } 

que hace:

table tr :nth-child(1), table tr :nth-child(4), table tr :nth-child(7) { 
    display: none; 
} 

Cuando todas las columnas se deben mostrar, borrar ésta regla anterior que se esconde columnas particulares.

0

¿Puedo sugerir algo como esto?

$(function() { 
    $('#show').click(function() { 
     var i; 
     for (i = 0; i < titles.length; i++) 
     { 
      ToggleHeadVisibility('SHOW', titles[i]); 
     } 
    }); 

    $('#hide').click(function() { 
     var i; 
     for (i = 0; i < titles.length; i++) 
     { 
      ToggleHeadVisibility('HIDE', titles[i]); 
     } 
    }); 
}); 

var titles = ['one', 'three', 'five']; 

function ToggleHeadVisibility(showHide, title) 
{ 
    var x = $('th[title=' + title + ']').index(); 
    var selectString = 'th:nth-child(' + (x + 1) + '), td:nth-child(' + (x + 1) + ')'; 
    var $set = $(selectString); 

    if (showHide === "SHOW") 
    { 
     $set.show(); 
    } 
    else if (showHide === "HIDE") 
    { 
     $set.hide(); 
    } 
} 

Creo que, de hecho, su lazo es el problema. Está iterando sobre cada th en la tabla. Si solo quiere encontrar unos específicos, ¿por qué no simplemente iterar sobre los que quiere encontrar?

Entonces, lo que sucede aquí es exactamente eso. Al hacer clic en el botón "mostrar" (u "ocultar"), iteramos sobre la matriz de títulos, llamando a ToggleHeadVisibility.

En esa función, obtenemos el índice del primer elemento con el título dado, y luego mostramos u ocultamos los nódulos n-child (x).

Lo he ejecutado sobre una mesa con 6 columnas, mostrando y escondiendo 3 a la vez, y más de 1000 filas. Es bastante rápido, por lo que está haciendo.

Tenga en cuenta que si su título s no son únicos, solo encontrará el primero en la tabla.

Cuestiones relacionadas