2010-06-29 3 views
6

J'ai une table html avec environ 30 colonnes et quelque part entre 10 à 500 lignes ish. Je voudrais montrer/cacher un ensemble de colonnes o un clic de bouton.jQuery afficher/cacher la colonne sur la performance de la grande table

J'ai essayé 2 approches

  1. itérer par thead e de la table et faire .show() ou .hide() sur la TH et TD.
  2. itérez le th th de la table et changez de classe pour afficher/masquer TH et TD.

La fonction est implémentée comme extrait suivant. Cependant, la performance n'est pas terrible. Afficher/Masquer dire 20 colonnes prend environ 5 ~ 10 secondes sur peut-être 80 ~ 120 lignes de données.

Je me demande simplement s'il y a quelque chose que nous pouvons faire pour le faire aller plus vite.

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

une comparaison intéressante afficher/masquer la performance http://www.learningjquery.com/2010/05/now-you-see-me-showhide-performance – Eatdoku

Répondre

9

Quelques suggestions:

  1. Alors que la construction d'une table, ajouter des classes CSS comme col1, col2, col3 etc. à en-tête et les cellules de données. Ensuite, vous pouvez simplement faire $("td.col1").hide(); pour masquer la colonne correspondante. Il est plus rapide que le n-ème sélecteur d'enfant.

  2. Dans IE et Firefox, vous pouvez définir un élément visibility: collapse sur un élément col pour réduire l'ensemble de la colonne. Ce sera beaucoup plus rapide. Malheureusement non pris en charge dans les navigateurs Webkit http://www.quirksmode.org/css/columns.html.Vous pouvez branchez votre code basé sur le navigateur afin qu'il soit rapide au moins dans IE et Firefox. Si votre table a un table-layout: fixed, cela peut améliorer considérablement les performances car votre navigateur n'a pas besoin de continuer à calculer la largeur des colonnes chaque fois que vous touchez la table comme en mode automatique. Envisagez de supprimer la table de l'arborescence DOM (via .remove()), effectuez l'opération d'affichage/masquage en bloc et réinsérez-la. C'est une règle générale lorsque vous souhaitez effectuer une opération en bloc sur l'arborescence DOM.

+0

J'ai eu le même problème que l'OP, avec probablement une table encore plus grande. Je me suis plutôt bien débrouillé en ajoutant des classes à table construites - comme au point 1 ci-dessus - et en changeant la définition css des classes dynamiquement avec Javascript, plutôt que d'utiliser les classes comme sélecteurs pour changer le style css en ligne. – undefinederror

1

De toute évidence, cette alternative est un peu souplement pour montrer et cacher des éléments:

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

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

Mais je soupçonne que votre vrai problème est que la boucle.

+0

il effectue ok avec 20 ~ 40 lignes ish. Je pense que la boucle de la 30th TH n'est pas vraiment un gros problème. C'est probablement plus sur le sélecteur "th: nth-child". Il y en a juste trop. Peut-être qu'il y a une autre approche? – Eatdoku

0

ici est la paix de code que je cachais « nième » colonne dans ma grille ...

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

Très semblable à la vôtre, sauf que j'utilisé bascule jQuery « montrer/cacher »;

il semble afficher/Masquer la colonne de 400 lignes sous ... 1 seconde

Borik

+0

Je l'ai essayé avec jQuery show() et hide() au lieu de ajouter/supprimer une classe comme vous pouvez le voir dans l'extrait de code (le code commenté). la performance est à peu près la même. – Eatdoku

0

Vous pouvez faire beaucoup dans le domaine de la mise en cache. Pour commencer, mettre en cache votre conteneur GRIDVIEW:

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

puis une rangée peut être mis en mémoire cache:

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

En outre, effectuer la peau réelle en utilisant l'ensemble, plutôt que d'un .each()

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

La mise en cache d'éléments à l'avant plutôt que d'interroger plusieurs fois le DOM avec $ et d'effectuer des actions sur des ensembles d'éléments plutôt que sur des boucles peut améliorer considérablement les performances.

0

L'itération à travers les lignes et les colonnes va toujours ralentir les choses. Essayez de manipuler les règles CSS directement pour éviter l'itération dans votre JavaScript et forcer le navigateur à le faire pour vous.

Vérifiez les plugins jQueryRule et jQueryCSSRule.

La manipulation directe des règles CSS peut être bénéfique si vous combinez toutes les règles. Voici un quick test avec 500 lignes et 50 colonnes. La plus grande partie du temps est consacrée au re-rendu, et le temps passé dans la fonction JavaScript me donne en moyenne 200-300 ms sur Chrome, et 0 ms sur Firefox. Actuellement, il utilise des API standard, mais il est trivial de l'étendre à IE.

Il fonctionne en créant un nouveau nœud <style> dans le document, et en y ajoutant toutes les manipulations de colonnes. L'idée clé est de combiner toutes les règles en une lorsque vous masquez certaines colonnes. Ainsi, au lieu de faire:

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

il fait:

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

Lorsque toutes les colonnes doivent être affichées en arrière, supprimez celui-ci règle ci-dessus qui se cache des colonnes particulières.

0

Puis-je suggérer quelque chose comme ça?

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

Je pense que c'est en fait votre problème. Vous itérez sur chaque th dans le tableau. Si vous voulez seulement en trouver des spécifiques, pourquoi ne pas simplement parcourir ceux que vous voulez trouver?

Donc, ce qui se passe ici est exactement cela. En cliquant sur le bouton "show" (ou "hide"), nous parcourons le tableau titles en appelant ToggleHeadVisibility.

Dans cette fonction, nous obtenons l'index du premier élément avec le titre donné, puis montrons ou cachons les nœuds nth-child (x). Je l'ai exécuté sur une table avec 6 colonnes, montrant et cachant 3 à la fois, et plus de 1000 lignes. C'est assez rapide, pour ce que ça fait. Notez que si votre titre s ne sont pas uniques, il ne trouvera que le premier dans la table.

Questions connexes