Search code examples
javascripthtmlscrollhtml-tabletableheader

Scrolling table with fixed header not working


From this thread, I picked up the code here.

I have copied it, but it does not work for me. The table looks like the example, but when I scroll the header scrolls up as well. I guess I must have made a mistake somewhere but cannot see it, can someone help me please?

#wrap {
  float: left;
  overflow: auto;
  height: 300px;
  border: 1px solid black;
}

table {
  border-spacing: 0;
}

table>*>tr>* {
  border-bottom: 1px solid black;
  border-right: 1px solid black;
}

table>tbody> :last-child>* {
  border-bottom: none;
}

th {
  background-color: lightskyblue;
}
<script>
  document.getElementById("wrap").addEventListener("scroll", function() {
    var translate = "translate(0," + this.scrollTop + "px)";
    this.querySelector("thread").style.transform = translate;
  });
</script>

<div id="wrap">
  <table>
    <thead>
      <tr>
        <th colspan="2">
          Colspanned Cell
        </th>
      </tr>
      <tr>
        <th>Foo bar baz qux quux lorem ipsum dolor sit amet consectetur adipisicing</th>
        <th>Foo Bar</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>This is a test</td>
        <td>This is a test</td>
      </tr>
      <tr>
        <td rowspan="3">Rowspanned cell</td>
        <td>Lorem ipsum dolor</td>
      </tr>
      <tr>
        <td>sit amet consectetur</td>
      </tr>
      <tr>
        <td>adipisicing</td>
      </tr>
      <tr>
        <td>testing 1 2 3</td>
        <td>testing 1 2 3</td>
      </tr>
      <tr>
        <td>a b c</td>
        <td>d e f</td>
      </tr>
      <tr>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td>testing 1 2 3 4</td>
        <td>testing 1 2 3 4 5 6 7 8 9 0</td>
      </tr>
      <tr>
        <td>The quick brown fox jumps over the lazy dog</td>
        <td>HELLO WORLD!!!!</td>
      </tr>
      <tr>
        <td>Foo bar</td>
        <td>baz qux</td>
      </tr>
      <tr>
        <td>quux</td>
        <td>foo<br/>bar<br/>baz<br/>qux<br/>quux</td>
      </tr>
      <tr>
        <td>THE</td>
        <td>END</td>
      </tr>
    </tbody>
  </table>
</div>


Solution

  • You have 2 problems with the provided snippet(s):

    • there's a typo in your javascript code you have this.querySelector("thread"). ..., and it should be this.querySelector("thead"). ... *without the "r"
    • second, and most important, the position of the "script tag. Things in HTML are parsed/evaluated/executed in the order they are in the source code. At the time the processor hits the script tag and executes it, the searched elements are not yet present in the DOM. For this you should either:

      • make that piece of code run after the whole document loaded. Ex.: inside jQuery(function(){ ... /* here */}) or adding handler to the body.
        or
      • (simpler) move the whole script tag/block down in the source code, after all the elements you are searching (I'd say, at least, after before closing the table and closing the wrapper div).