30 votes

Tableau HTML avec colonnes et en-têtes fixes (figés)

J'ai cherché sur le web pour la façon de faire un tableau avec fixe (surgelés) et colonnes d'en-tête. Semblerait que j'ai enfin trouvé la solution et l'a modifié pour mes besoins.

Il y a d'origine violon est ici.

Ici est ma solution modifiée. Je l'ai testé en Chrome (version: 55.0.2883.87 m) et Firefox (version: 51.0.1).

Le problème est qu'il fonctionne pas complètement dans IE (version: 11.0.9600.18427). Pendant le défilement horizontal gelé une partie de l'en-tête est de se défile trop. Quelqu'un pourrait-il m'aider à le faire fonctionner sous IE? Et encore une question: est-ce l'approche sécuritaire à utiliser? Je veux dire, si c'est à l'aide de certains comportement quelconque, une partie de l'avenir des navigateurs ou même certains des navigateurs modernes peuvent afficher mon tableau dans un mauvais sens, et il est préférable d'utiliser une solution de sécurité avec un peu de tables différentes et la synchronisation de la position de défilement et de lignes de hauteur. UPD: encore une question: comment faire pour faire ce travail stable sur les appareils mobiles?

Voici un code qui illustre l'approche:

$(document).ready(function() {
  $('tbody').scroll(function(e) { //detect a scroll event on the tbody
  	/*
    Setting the thead left value to the negative valule of tbody.scrollLeft will make it track the movement
    of the tbody element. Setting an elements left value to that of the tbody.scrollLeft left makes it maintain 			it's relative position at the left of the table.    
    */
    $('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling
    $('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first cell of the header
    $('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody
  });
});
.container {
  height:200px; 
  width:400px;
  overflow: hidden;
}

table {
  position: relative;
  background-color: #aaa;
  border-collapse: collapse;
table-layout: fixed;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}


/*thead*/
thead {
  position: relative;
  display: block; /*seperates the header from the body allowing it to be positioned*/
}

thead th {
  background-color: #99a;
  min-width: 120px;
  border: 1px solid #222;
}

thead th:nth-child(1) {/*first cell in the header*/
  position: relative;
  background-color: #88b;
}


/*tbody*/
tbody {
  flex: 1;
  position: relative;
  display: block; /*seperates the tbody from the header*/
  overflow: auto;
}

tbody td {
  background-color: #bbc;
  min-width: 120px;
  border: 1px solid #222;
}

tbody tr td:nth-child(1) {  /*the first cell in each tr*/
  position: relative;
  background-color: #99a;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container">

  <table>
    <thead>
      <tr>
        <th>Name<br/>123</th>
        <th>Town</th>
        <th>County</th>
        <th>Age</th>
        <th>Profession</th>
        <th>Anual Income</th>
        <th>Matital Status</th>
        <th>Children</th>
      </tr>
       <tr>
        <th>Name</th>
        <th>Town</th>
        <th>County</th>
        <th>Age<br/>123<br/>321</th>
        <th>Profession</th>
        <th>Anual Income</th>
        <th>Matital Status</th>
        <th>Children</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>John Smith</td>
        <td>Macelsfield</td>
        <td>Cheshire<br/>123</td>
        <td>52</td>
        <td>Brewer</td>
        <td>£47,000</td>
        <td>Married</td>
        <td>2</td>
      </tr>
      <tr>
        <td>Jenny Jones<br/>123<br/>312</td>
        <td>Threlkeld</td>
        <td>Cumbria</td>
        <td>34</td>
        <td>Shepherdess</td>
        <td>£28,000</td>
        <td>Single</td>
        <td>0</td>
      </tr>
      <tr>
        <td>Peter Frampton</td>
        <td>Avebury</td>
        <td>Wiltshire</td>
        <td>57</td>
        <td>Musician</td>
        <td>£124,000</td>
        <td>Married</td>
        <td>4</td>
      </tr>
      <tr>
        <td>Simon King</td>
        <td>Malvern</td>
        <td>Worchestershire</td>
        <td>48</td>
        <td>Naturalist</td>
        <td>£65,000</td>
        <td>Married</td>
        <td>2</td>
      </tr>
      <tr>
        <td>Lucy Diamond</td>
        <td>St Albans</td>
        <td>Hertfordshire</td>
        <td>67</td>
        <td>Pharmasist</td>
        <td>Retired</td>
        <td>Married</td>
        <td>3</td>
      </tr>
      <tr>
        <td>Austin Stevenson</td>
        <td>Edinburgh</td>
        <td>Lothian </td>
        <td>36</td>
        <td>Vigilante</td>
        <td>£86,000</td>
        <td>Single</td>
        <td>Unknown</td>
      </tr>
      <tr>
        <td>Wilma Rubble</td>
        <td>Bedford</td>
        <td>Bedfordshire</td>
        <td>43</td>
        <td>Housewife</td>
        <td>N/A</td>
        <td>Married</td>
        <td>1</td>
      </tr>
      <tr>
        <td>Kat Dibble</td>
        <td>Manhattan</td>
        <td>New York</td>
        <td>55</td>
        <td>Policewoman</td>
        <td>$36,000</td>
        <td>Single</td>
        <td>1</td>
      </tr>
      <tr>
        <td>Henry Bolingbroke</td>
        <td>Bolingbroke</td>
        <td>Lincolnshire</td>
        <td>45</td>
        <td>Landowner</td>
        <td>Lots</td>
        <td>Married</td>
        <td>6</td>
      </tr>
      <tr>
        <td>Alan Brisingamen</td>
        <td>Alderley</td>
        <td>Cheshire</td>
        <td>352</td>
        <td>Arcanist</td>
        <td>A pile of gems</td>
        <td>Single</td>
        <td>0</td>
      </tr>
    </tbody>
  </table>
  
</div>
</body>

8voto

Matt Spinks Points 3941

C'est très étrange. Il semble que le code problématique est cette ligne:

$('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling

Il ressemble à IE11 poignées de positionnement relatif des éléments imbriqués de manière différente (que le Chrome et les autres navigateurs). Dans ce cas, vous êtes de positionnement thead avec le positionnement relatif avec un décalage. Vous êtes également le positionnement thead th (c'est les enfants) avec un décalage et le positionnement relatif. Chrome semble être le positionnement thead par rapport à l' table, puis de positionnement th par rapport à l' thead. IE11, d'autre part, semble être le positionnement thead par rapport à l' table, puis th seulement hérite de la même quel que soit le positionnement de son propre positionnement.

Un correctif pour résoudre ce devrait être le suivant: sur IE11, gérer le positionnement différemment pour thead. Au lieu de définir le positionnement sur le parent thead, définir le positionnement sur l' thead th - éléments. De cette façon, votre première colonne ne sera pas "forcé" d'hériter thead's de positionnement (IE).

$(document).ready(function() {
  var isIE11 = !!navigator.userAgent.match(/Trident.*rv\:11\./);
  var customScroller;
  if (isIE11)
    customScroller = function() {
      $('thead th').css("left", -$("tbody").scrollLeft()); //if using IE11, fix the th element 
    };
  else
    customScroller = function() {
      $('thead').css("left", -$("tbody").scrollLeft()); //if not using IE11, fix the thead element
    };

  $('tbody').scroll(function(e) { //detect a scroll event on the tbody
    /*
    Setting the thead left value to the negative valule of tbody.scrollLeft will make it track the movement
    of the tbody element. Setting an elements left value to that of the tbody.scrollLeft left makes it maintain             it's relative position at the left of the table.    
    */
    customScroller(); //fix the thead relative to the body scrolling
    $('thead th:nth-child(1)').css("left", $("tbody").scrollLeft());
//fix the first cell of the header
    $('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody
  });
});

Voici un exemple complet avec votre code, montrant les différentes manipulations basées sur le navigateur:

https://jsfiddle.net/8tx4xfhx/5/

Alsol, il serait agréable de voir si quelqu'un a remarqué ce problème avant. Il semble que IE11 poignées imbriquée positionnement relatif différemment que les autres navigateurs. Est-il un spec quelque part qui définit ce qu'est la norme devrait être? Devrait positionnement relatif être héréditaire, comme IE fait-il? Ou devrait le positionnement relatif toujours par rapport à la mère? Je pense que le dernier. Mais les performances considérations doivent être prises.

8voto

Vous devez essayer l'exemple de code ci-dessous avec référence à jquery.floatThead.js.

                     var $demoTable = $("div.table-responsive table");
                    $demoTable.floatThead({
                        top: 200,
                        scrollContainer: function ($table) {                                
                            return $table.closest('.table-responsive');
                        },
                        position: 'absolute'
                    });
 

vous devez obtenir la référence du fichier jquery.floatThead.js et essayer de l'appliquer sur la table.

Vous pouvez vérifier cela en travaillant sur le lien ci-dessous. http://mkoryak.github.io/floatThead/

7voto

nashcheez Points 4004

Généralement pour les surgelés lignes et colonnes, je préfère toujours utiliser un css seule solution pour une meilleure compatibilité des navigateurs.

J'ai essayé de reproduire ici votre code avec un css seule solution.

Je suis en train de travailler sur un mac, donc n'ont pas accès à IE. Veuillez vérifier si sa fonctionne bien sur la même chose.

Mise à jour de violon: https://jsfiddle.net/nashcheez/bzuasLcz/81/

Reportez-vous code:

table {
  position: relative;
  width: 700px;
  background-color: #aaa;
  overflow: hidden;
  border-collapse: collapse;
}
/*thead*/

thead {
  position: relative;
  display: block;
  /*seperates the header from the body allowing it to be positioned*/
  width: 700px;
  overflow: visible;
}
thead th {
  background-color: #99a;
  min-width: 120px;
  height: 36px;
  min-height: 36px;
  border: 1px solid #222;
}
thead th:nth-child(1) {
  /*first cell in the header*/
  position: relative;
  display: block;
  background-color: #88b;
}
tbody tr td:nth-child(2) {
  margin-left: 124px;
  display: block;
}
/*tbody*/

tbody {
  display: block;
  width: 700px;
  height: 239px;
  overflow-y: auto;
}
tbody td {
  background-color: #bbc;
  min-width: 120px;
  border: 1px solid #222;
  height: 36px;
  min-height: 36px;
}
tbody tr td:nth-child(1) {
  /*the first cell in each tr*/
  position: absolute;
  display: inline-block;
  background-color: #99a;
}
<body>
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Town</th>
        <th>County</th>
        <th>Age</th>
        <th>Profession</th>
        <th>Anual Income</th>
        <th>Matital Status</th>
        <th>Children</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>John Smith</td>
        <td>Macelsfield</td>
        <td>Cheshire</td>
        <td>52</td>
        <td>Brewer</td>
        <td>£47,000</td>
        <td>Married</td>
        <td>2</td>
      </tr>
      <tr>
        <td>Jenny Jones</td>
        <td>Threlkeld</td>
        <td>Cumbria</td>
        <td>34</td>
        <td>Shepherdess</td>
        <td>£28,000</td>
        <td>Single</td>
        <td>0</td>
      </tr>
      <tr>
        <td>Peter Frampton</td>
        <td>Avebury</td>
        <td>Wiltshire</td>
        <td>57</td>
        <td>Musician</td>
        <td>£124,000</td>
        <td>Married</td>
        <td>4</td>
      </tr>
      <tr>
        <td>Simon King</td>
        <td>Malvern</td>
        <td>Worchestershire</td>
        <td>48</td>
        <td>Naturalist</td>
        <td>£65,000</td>
        <td>Married</td>
        <td>2</td>
      </tr>
      <tr>
        <td>Lucy Diamond</td>
        <td>St Albans</td>
        <td>Hertfordshire</td>
        <td>67</td>
        <td>Pharmasist</td>
        <td>Retired</td>
        <td>Married</td>
        <td>3</td>
      </tr>
      <tr>
        <td>Austin Stevenson</td>
        <td>Edinburgh</td>
        <td>Lothian</td>
        <td>36</td>
        <td>Vigilante</td>
        <td>£86,000</td>
        <td>Single</td>
        <td>Unknown</td>
      </tr>
      <tr>
        <td>Wilma Rubble</td>
        <td>Bedford</td>
        <td>Bedfordshire</td>
        <td>43</td>
        <td>Housewife</td>
        <td>N/A</td>
        <td>Married</td>
        <td>1</td>
      </tr>
      <tr>
        <td>Kat Dibble</td>
        <td>Manhattan</td>
        <td>New York</td>
        <td>55</td>
        <td>Policewoman</td>
        <td>$36,000</td>
        <td>Single</td>
        <td>1</td>
      </tr>
      <tr>
        <td>Henry Bolingbroke</td>
        <td>Bolingbroke</td>
        <td>Lincolnshire</td>
        <td>45</td>
        <td>Landowner</td>
        <td>Lots</td>
        <td>Married</td>
        <td>6</td>
      </tr>
      <tr>
        <td>Alan Brisingamen</td>
        <td>Alderley</td>
        <td>Cheshire</td>
        <td>352</td>
        <td>Arcanist</td>
        <td>A pile of gems</td>
        <td>Single</td>
        <td>0</td>
      </tr>
    </tbody>
  </table>
</body>

1voto

Jared Clemence Points 796

Le problème est que IE ne permettent pas d'ajuster l' left attribut d'une cellule dans une ligne indépendante de l'intégralité de la ligne. Nous pouvons voir cela en éditant le DOM en utilisant directement le développeur de la fenêtre dans IE et le développeur de la fenêtre dans le navigateur Chrome.

Dans google Chrome, lorsque vous faites défiler à gauche et à droite, vous pouvez voir dans l'Élément de la visionneuse de l' left attribut est modifié sur l'élément lui-même, qui remplace toutes les CSS. On peut recharger la page et définissez l'attribut d'élément manuellement dans ce même écran: style:'left:300px', et nous verrons la cellule d'en-tête se déplacer vers la droite 300px et de survoler le reste des cellules d'en-tête. C'est le bon comportement et le comportement qui fait que cette méthode de travail.

Si nous faisons la même chose dans IE et d'ajouter style: 'left:300px' à la ème élément, nous allons voir que la cellule ne se déplace pas. Rien ne nous le faisons pour les attributs de style de cette cellule va l'amener à quitter sa place dans le tableau. C'est cette "fonctionnalité" de IE qui est à l'origine de la méthode à l'échec. IE est d'insister sur le maintien de la cellule afin peu importe ce que les attributs sont appliqués aux éléments à l'intérieur d'une ligne.

Le truc, c'est de travailler autour de cette complication d'une manière qui rend tous les navigateurs heureux. Il y a beaucoup de façons de le faire, mais je serais probablement utiliser deux tables, et utiliser des DIVs pour les positionner de sorte que les bords de match. Je voudrais ajouter du javascript, de sorte que si l'on tbody défiler vers le haut ou vers le bas qu'elle affecte les autres tbody de la même manière. Si elle fait défiler à droite ou à gauche, rien n'arrive à la première table, qui détient vos surgelés en-têtes de colonne, et le droit de la table se déplace dans la direction de défilement comme prévu.

En utilisant deux tables, c'est à dire de ne plus associer l'en-tête que vous essayez de gel avec l'en-tête qui est en mouvement. Attention CSS se déguiser votre hack et la table d'apparaître comme un tableau.

Bonne chance et amusez-vous!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X