Rolf B: Tabellenspalte bei :hover markieren

Beitrag lesen

Hallo Matthias,

ab Internet Explorer 10 geht dies hier:

<table class="hovertable">
  <colgroup><col><col><col><col></colgroup>
  <thead>
    <tr>
      <th>Col 1</th>
      <th>Col 2</th>
      <th>Col 3</th>
      <th>Col 4</th>
    </tr>
  </thead>
  <tbody>
    <tr><td></td><td></td><td></td><td></td></tr>
    <tr><td></td><td></td><td></td><td></td></tr>
    <tr><td colspan=2></td><td></td><td></td></tr>
    <tr><td></td><td></td><td></td><td></td></tr>
  </tbody>
</table>    

Das CSS ist egal, und dies ist mein JS. Man kann es bspw. in eine IIFE am Ende des Body stellen. Oder in ein Modul, zusammen mit einem Ready-Handler.

function markColumn(evt) {
  if (!evt.target) return;

  var cell = evt.target;
  if (!(evt.target instanceof HTMLTableCellElement)) return;
  
  var table = cell.parentElement;
  while (table && !(table instanceof HTMLTableElement))
     table = table.parentElement;
     
  if (!table || !table.classList.contains("hovertable")) return;
  
  var n = cell.cellIndex + 1;
  var color = evt.type == "mouseover" ? "#ffccaa" : "";
  if (n > 2) {
    let x = table.querySelector("col:nth-child("+n+")").style.background = color;
  }
}

document.addEventListener("mouseover", markColumn);
document.addEventListener("mouseout", markColumn);

Ich registriere mouseover und mouseout am Dokument und suche das table-Element zur cell im Eventhandler. Statt dessen könnte man auch mit querySelectorAll alle .hovertables suchen und die Events auf den Tables registrieren. Dann bekommt man das table-Element als currentTarget geschenkt. Beides geht, beides hat Vor- und Nachteile.

Es ist jedenfalls falsch, in der markColumns Methode eine irgendwie geartete Kennzeichnung der Table fest zu verdrahten. markColumn darf nicht auf eine spezielle ID oder Klasse festgelegt sein.

Statt der parentElement Suche könnte man auch closest('table') verwenden, das braucht dann einen Polyfill für den Internet Explorer oder der Highlighter funktioniert dort dann nicht. Wenn man das Event auf den tables registriert, hätte man auch eine Erleichterung für die Suche nach dem Table-Element, denn dann ist das currentTarget die Table und man muss sie nicht mehr suchen.

Die classList.contains Eigenschaft funktioniert ab IE10, das ist mMn heutzutage hinreichend.

Statt die Zellen mit Hintergrund zu versehen, setze ich die background Eigenschaft auf dem col-Element. Dazu muss die Table eine Dummy-colgroup-Definition bekommen; das ist jedenfalls deutlich simpler als die Spalte abzulaufen. Es funktioniert nur nicht, wenn die Zellen eine eigene Farbgebung haben.

Um mit colspans klarzukommen, muss man vermutlich über Mauszeigerpositionen arbeiten. Dazu muss man aber erstmal die Beginn-Offsets aller ungespannten Spalten finden, z.B. über die th im thead - die col-Elemente haben keine Position. Und dann hat man das Problem, dass dann, wenn eine Spalte markiert wird wo eine colspan-Zelle drin ist, die Markierung aus der Spalte hinausläuft. Um es visuell ganz sauber zu haben, muss man vermutlich tatsächlich der Table ein Pseudoelement überlagern.

Rolf

--
sumpsi - posui - clusi