web-dev-qa-db-fra.com

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

Étant donné le 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 l'un des éléments td est déjà disponible, comment puis-je trouver l'élément th correspondant?

var $td = IveGotThisCovered();
var $th = GetTableHeader($td);
77
GenericTypeTea
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());
128
user113716
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 plusieurs.

7
Adam

Solution qui gère colspan

J'ai une solution basée sur la correspondance du bord gauche du td au bord gauche du th correspondant. Il devrait gérer les colspans arbitrairement complexes.

J'ai modifié le scénario de test pour montrer que la variable colspan arbitraire était gérée 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>
4
doug65536

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

var tdIndex = $td.index() + 1;
var $th = $('#table tr').find('th:nth-child(' + tdIndex + ')');
4
rebelliard

La solution Pure 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) + ')')
2
JeromeJ

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: nième enfant (1), e: nième enfant (1)'). toggle ();

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

Recherchez la correspondance th pour une td, en tenant compte des problèmes liés à colspan 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>

0
vsync