Comment puis-je obtenir l'en-tête de tableau correspondant (th) à partir d'une cellule de tableau (td)?

86

Compte tenu du tableau suivant, comment puis-je obtenir l'en-tête de tableau correspondant pour chaque élément td?

<table>
    <thead> 
        <tr>
            <th id="name">Name</th>
            <th id="address">Address</th>
        </tr>
    </thead> 
    <tbody>
        <tr>
            <td>Bob</td>
            <td>1 High Street</td>
        </tr>
    </tbody>
</table>

Étant donné que j'ai actuellement l'un des tdéléments à ma disposition, comment puis-je trouver l' thélément correspondant ?

var $td = IveGotThisCovered();
var $th = GetTableHeader($td);
djdd87
la source
2
Aucune des réponses ne prend en compte la possibilité que le th puisse avoir un colspan supérieur à 1, ce qui est mon cas d'utilisation :(
Dexygen
1
@GeorgeJempty Ma réponse gère les colspans.
doug65536

Réponses:

137
var $th = $td.closest('tbody').prev('thead').find('> tr > th:eq(' + $td.index() + ')');

Ou un peu simplifié

var $th = $td.closest('table').find('th').eq($td.index());
utilisateur113716
la source
2
si vous mettez plus de tables dans vos tables, utilisez à la .parent('table')place de.closest('table')
Dead.Rabit
14
qu'en est-il des colspans?
bradvido
@bradvido - Ma réponse tient compte de cela
vsync
10
var $th = $("table thead tr th").eq($td.index())

Il serait préférable d'utiliser un identifiant pour référencer la table s'il y en a plus d'un.

Adam
la source
Plus d'un tableau peut être dans la page, ce qui rend cette solution peu fiable
vsync
5

Solution qui gère colspan

J'ai une solution basée sur la correspondance du bord tdgauche du bord gauche du correspondant th. Il doit gérer des colspans arbitrairement complexes.

J'ai modifié le cas de test pour montrer que l'arbitraire colspanest géré correctement.

Démo en direct

JS

$(function($) {
  "use strict";

  // Only part of the demo, the thFromTd call does the work
  $(document).on('mouseover mouseout', 'td', function(event) {
    var td = $(event.target).closest('td'),
        th = thFromTd(td);
    th.parent().find('.highlight').removeClass('highlight');
    if (event.type === 'mouseover')
      th.addClass('highlight');
  });

  // Returns jquery object
  function thFromTd(td) {
    var ofs = td.offset().left,
        table = td.closest('table'),
        thead = table.children('thead').eq(0),
        positions = cacheThPositions(thead),
        matches = positions.filter(function(eldata) {
          return eldata.left <= ofs;
        }),
        match = matches[matches.length-1],
        matchEl = $(match.el);
    return matchEl;
  }

  // Caches the positions of the headers,
  // so we don't do a lot of expensive `.offset()` calls.
  function cacheThPositions(thead) {
    var data = thead.data('cached-pos'),
        allth;
    if (data)
      return data;
    allth = thead.children('tr').children('th');
    data = allth.map(function() {
      var th = $(this);
      return {
        el: this,
        left: th.offset().left
      };
    }).toArray();
    thead.data('cached-pos', data);
    return data;
  }
});

CSS

.highlight {
  background-color: #EEE;
}

HTML

<table>
    <thead> 
        <tr>
            <th colspan="3">Not header!</th>
            <th id="name" colspan="3">Name</th>
            <th id="address">Address</th>
            <th id="address">Other</th>
        </tr>
    </thead> 
    <tbody>
        <tr>
            <td colspan="2">X</td>
            <td>1</td>
            <td>Bob</td>
            <td>J</td>
            <td>Public</td>
            <td>1 High Street</td>
            <td colspan="2">Postfix</td>
        </tr>
    </tbody>
</table>
doug65536
la source
J'ai développé le cas de test pour utiliser simultanément des combinaisons arbitraires colspandans les en-têtes et les lignes, et cela fonctionnait toujours. Je serais heureux d'entendre tous les cas que vous pouvez trouver qui ne fonctionneront pas.
doug65536
4

Vous pouvez le faire en utilisant l'index de td:

var tdIndex = $td.index() + 1;
var $th = $('#table tr').find('th:nth-child(' + tdIndex + ')');
rebelliard
la source
1
N'oubliez pas que .index()c'est une base zéro et nth-childune base unique. Donc, le résultat serait de un. : o)
user113716
3

La solution purement JavaScript:

var index = Array.prototype.indexOf.call(your_td.parentNode.children, your_td)
var corresponding_th = document.querySelector('#your_table_id th:nth-child(' + (index+1) + ')')
Jeromej
la source
1

Trouvez la correspondance thpour a td, en tenant compte colspandes problèmes d'index.

$('table').on('click', 'td', get_TH_by_TD)

function get_TH_by_TD(e){
   var idx = $(this).index(),
       th, th_colSpan = 0;

   for( var i=0; i < this.offsetParent.tHead.rows[0].cells.length; i++ ){
      th = this.offsetParent.tHead.rows[0].cells[i];
      th_colSpan += th.colSpan;
      if( th_colSpan >= (idx + this.colSpan) )
        break;
   }
   
   console.clear();
   console.log( th );
   return th;
}
table{ width:100%; }
th, td{ border:1px solid silver; padding:5px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Click a TD:</p>
<table>
    <thead> 
        <tr>
            <th colspan="2"></th>
            <th>Name</th>
            <th colspan="2">Address</th>
            <th colspan="2">Other</th>
        </tr>
    </thead> 
    <tbody>
        <tr>
            <td>X</td>
            <td>1</td>
            <td>Jon Snow</td>
            <td>12</td>
            <td>High Street</td>
            <td>Postfix</td>
            <td>Public</td>
        </tr>
    </tbody>
</table>

vsync
la source
0

C'est simple, si vous les référencez par index. Si vous souhaitez masquer la première colonne, vous devez:

Copier le code

$('#thetable tr').find('td:nth-child(1),th:nth-child(1)').toggle();

La raison pour laquelle j'ai d'abord sélectionné toutes les lignes de la table, puis les td et les th qui étaient le nième enfant est pour que nous n'ayons pas à sélectionner la table et toutes les lignes de la table deux fois. Cela améliore la vitesse d'exécution du script. Gardez à l'esprit, nth-child()est 1basé, non 0.

مهدی عابدی برنامه نویس و مشاور
la source