Wie kann ich den entsprechenden Tabellenkopf (th) aus einer Tabellenzelle (td) abrufen?


86

Wie würde ich in der folgenden Tabelle den entsprechenden Tabellenkopf für jedes td-Element erhalten?

<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>

tdWie kann ich das entsprechende thElement finden , da mir derzeit bereits eines der Elemente zur Verfügung steht ?

var $td = IveGotThisCovered();
var $th = GetTableHeader($td);

2
Keine der Antworten berücksichtigt die Möglichkeit, dass der th einen Colspan größer als 1 hat, was mein Anwendungsfall ist :(
Dexygen

1
@ GeorgeJempty Meine Antwort behandelt Colspans.
Doug65536

Antworten:


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

Oder ein bisschen vereinfacht

var $th = $td.closest('table').find('th').eq($td.index());

2
Wenn Sie mehr Tabellen in Ihre Tabellen .parent('table').closest('table')
einfügen

14
Was ist mit Colspans?
Bradvido

@bradvido - Meine Antwort berücksichtigt das
vsync

10
var $th = $("table thead tr th").eq($td.index())

Es ist am besten, eine ID zu verwenden, um auf die Tabelle zu verweisen, wenn es mehr als eine gibt.


Möglicherweise befindet sich mehr als eine Tabelle auf der Seite, wodurch diese Lösung unzuverlässig wird
vsync

5

Lösung, die handhabt colspan

Ich habe eine Lösung, die darauf basiert, den linken Rand des tdmit dem linken Rand des entsprechenden zu vergleichenth . Es sollte beliebig komplexe Colspans verarbeiten.

Ich habe den Testfall geändert, um zu zeigen, dass Beliebig colspankorrekt behandelt wird.

Live-Demo

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>

Ich habe den Testfall erweitert, um gleichzeitig beliebige Kombinationen colspanin den Überschriften und Zeilen zu verwenden, und es hat immer noch funktioniert. Ich würde mich freuen, von allen Fällen zu hören, die damit nicht funktionieren.
Doug65536

4

Sie können dies mithilfe des Index von td tun:

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

1
Denken Sie daran, dass dies auf .index()Null und auf nth-childEins basiert. Das Ergebnis wäre also um eins falsch. : o)
user113716

3

Reine JavaScript-Lösung:

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) + ')')

1

Finden Sie eine Übereinstimmung thfür a tdunter Berücksichtigung von colspanIndexproblemen.

$('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

Das ist einfach, wenn Sie sie nach Index referenzieren. Wenn Sie die erste Spalte ausblenden möchten, würden Sie:

Code kopieren

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

Der Grund, warum ich zuerst alle Tabellenzeilen und dann sowohl td als auch th ausgewählt habe, die das n-te Kind waren, ist, dass wir die Tabelle und alle Tabellenzeilen nicht zweimal auswählen müssen. Dies verbessert die Geschwindigkeit der Skriptausführung. Denken Sie daran, nth-child()wird 1basierend, nicht 0.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.