Der Tabellenkopf bleibt oben fixiert, wenn der Benutzer ihn mit jQuery aus der Ansicht scrollt


145

Ich versuche, eine HTML-Tabelle zu entwerfen, in der der Header oben auf der Seite bleibt, wenn UND NUR wenn der Benutzer ihn aus der Ansicht scrollt. Zum Beispiel kann die Tabelle 500 Pixel von der Seite entfernt sein. Wie kann ich sie so gestalten, dass sie, wenn der Benutzer den Header aus der Ansicht scrollt (der Browser erkennt, dass er nicht mehr in der Windows-Ansicht angezeigt wird), oben bleibt ? Kann mir jemand eine Javascript-Lösung dafür geben?

<table>
  <thead>
    <tr>
      <th>Col1</th>
      <th>Col2</th>
      <th>Col3</th>
    </tr>
  </thead>
  <tbody>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
  </tbody>
</table>

Im obigen Beispiel möchte ich, dass <thead>die Seite mit der Seite gescrollt wird, wenn sie nicht mehr angezeigt wird.

WICHTIG: Ich suche NICHT nach einer Lösung, bei der <tbody>eine Bildlaufleiste angezeigt wird (Überlauf: Auto).




Ich habe dies für eine andere Frage beantwortet, bitte werfen Sie einen Blick darauf. stackoverflow.com/a/56764334/9388978
Ersel Aktas

Antworten:


131

Sie würden so etwas tun, indem Sie auf den scrollEreignishandler tippen windowund einen anderen tablemit einer festen Position verwenden, um die Kopfzeile oben auf der Seite anzuzeigen.

HTML:

<table id="header-fixed"></table>

CSS:

#header-fixed {
    position: fixed;
    top: 0px; display:none;
    background-color:white;
}

JavaScript:

var tableOffset = $("#table-1").offset().top;
var $header = $("#table-1 > thead").clone();
var $fixedHeader = $("#header-fixed").append($header);

$(window).bind("scroll", function() {
    var offset = $(this).scrollTop();

    if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
        $fixedHeader.show();
    }
    else if (offset < tableOffset) {
        $fixedHeader.hide();
    }
});

Dies zeigt den Tabellenkopf an, wenn der Benutzer weit genug nach unten scrollt, um den ursprünglichen Tabellenkopf auszublenden. Es wird wieder ausgeblendet, wenn der Benutzer die Seite wieder weit genug nach oben gescrollt hat.

Arbeitsbeispiel: http://jsfiddle.net/andrewwhitaker/fj8wM/


60
Ich habe darüber nachgedacht, aber was ist, wenn sich die Breite der Kopfspalten je nach Inhalt ändert? Wenn die Spaltenbreiten nicht festgelegt sind, kann es sein, dass Ihre Kopfzeile nicht mit den Inhaltszeilen übereinstimmt. Nur ein Gedanke.
Yzmir Ramirez

16
Dieses Beispiel funktioniert nicht, wenn die Namen der Spaltenüberschriften kürzer als die Spaltendatenwerte sind. Versuchen Sie, diese Geige so zu ändern, dass sie Werte wie infoooooooo anstelle von info enthält. Ich denke an eine Art fest codierte Breite, die beim Klonen der Tabelle festgelegt wird.
whiterook6

6
Dies hat erhebliche Einschränkungen, am wenigsten beim Versuch, die Tabelle in einem anderen Container als zu verwenden window. mkoryak.github.io/floatThead bietet eine allgemeinere Lösung.
Yuck

13
Dies könnte jedem helfen, der dynamische Breiten benötigt. Es ist eine Gabelung von @AndrewWhitaker: jsfiddle.net/noahkoch/wLcjh/1
Noah Koch

1
@NoahKoch fester Header mit Ihrer Lösung kann immer noch nicht so breit sein wie der ursprüngliche Kopf, wenn die ursprünglichen Zellen gepolstert sind. Ich habe Ihre Lösung verbessert, um doppelten Zellen Polster hinzuzufügen. JSFiddles Gabel: jsfiddle.net/1n23m69u/2
fandasson

46

Nun, ich habe versucht, den gleichen Effekt zu erzielen, ohne auf Spalten mit fester Größe zurückzugreifen oder eine feste Höhe für den gesamten Tisch zu haben.

Die Lösung, die ich gefunden habe, ist ein Hack. Es besteht darin, die gesamte Tabelle zu duplizieren, dann alles außer dem Header auszublenden und dafür zu sorgen, dass diese eine feste Position hat.

HTML

<div id="table-container">
<table id="maintable">
    <thead>
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th>Col3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>some really long line here instead</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
                <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
                <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
    </tbody>
</table>
<div id="bottom_anchor"></div>
</div>

CSS

body { height: 1000px; }
thead{
    background-color:white;
}

Javascript

function moveScroll(){
    var scroll = $(window).scrollTop();
    var anchor_top = $("#maintable").offset().top;
    var anchor_bottom = $("#bottom_anchor").offset().top;
    if (scroll>anchor_top && scroll<anchor_bottom) {
    clone_table = $("#clone");
    if(clone_table.length == 0){
        clone_table = $("#maintable").clone();
        clone_table.attr('id', 'clone');
        clone_table.css({position:'fixed',
                 'pointer-events': 'none',
                 top:0});
        clone_table.width($("#maintable").width());
        $("#table-container").append(clone_table);
        $("#clone").css({visibility:'hidden'});
        $("#clone thead").css({'visibility':'visible','pointer-events':'auto'});
    }
    } else {
    $("#clone").remove();
    }
}
$(window).scroll(moveScroll); 

Siehe hier: http://jsfiddle.net/QHQGF/7/

Bearbeiten: Der Code wurde aktualisiert, sodass der Kopf Zeigerereignisse empfangen kann (sodass Schaltflächen und Links in der Kopfzeile weiterhin funktionieren). Dies behebt das von luhfluh und Joe M. gemeldete Problem.

Neue jsfiddle hier: http://jsfiddle.net/cjKEx/


3
Ich habe das zuerst versucht. Das Problem dabei ist, dass die Größe der Elemente im Header vom Inhalt der Tabelle abhängt. Wenn Sie eine Zeile mit großem Inhalt haben, wächst die gesamte Spalte einschließlich der Kopfzeile. Wenn Sie nur den Thead klonen, verlieren Sie diese Informationen und erhalten nicht den gewünschten Effekt. Siehe Yzmir Ramirez 'Kommentar zur akzeptierten Antwort. Dies ist der einzige Weg, den ich gefunden habe, der ohne Spalten mit fester Breite funktioniert. Es ist nicht sauber, ich weiß, so habe ich gesagt, es war ein Hack.
Entropie

1
Oh, ich habe es. Diese Methode ist großartig, weil sie mit flüssigen Säulen funktioniert. Ich habe ein wenig gegoogelt und konnte keine andere mit dieser Funktionalität finden. Wie auch immer, wenn ich es irgendwie schaffen werde, werde ich es hier erwähnen
M2_

1
@luhfluh, ja, das Problem war auf die Zeigerereignisse zurückzuführen: keine in der geklonten Tabelle. Dies wird verwendet, damit Klicks durch den Klon und zur ursprünglichen Tabelle gelangen. Das Zurücksetzen in den Header der geklonten Tabelle, sodass der Header (und nur der Header) anklickbar ist, behebt das Problem. Ich habe meinen Beitrag aktualisiert, um dies widerzuspiegeln :)
Entropie

4
Problem beim Hinzufügen eines Rahmens auf <thead> <th>
Jam Ville

1
@ JamVille Weil geklonte Tabelle hat visibility: hidden. Sie können nur verstecken #clone tbodyund danach können Sie Grenze setzen ... Working fiddle: jsfiddle.net/QHQGF/1707
Lajdák Marek

46

Reines CSS (ohne IE11-Unterstützung):

table th {
    position: -webkit-sticky; // this is for all Safari (Desktop & iOS), not for Chrome
    position: sticky;
    top: 0;
    z-index: 5;
    background: #fff;
}

1
Ich sehe nicht einmal, dass dies in Chrome funktioniert. Die Inspektionswerkzeuge werden -webkit-stickyals ungültiger Wert für angezeigt position.
Karmenismus

@carmenism -webkit-stickyist für Safari (Desktop & iOS), nicht für Chrome. position: stickyfunktioniert in Chrome ab Version 56. Sie sollten BEIDE Regeln festlegen: -webkit-stickyund zwar stickygenau in derselben Reihenfolge wie in meinem Codebeispiel. Safari bekommt webkit-stickyund alle anderen Browser überschreiben es mit sticky.
Ihor Zenich

2
Ich konnte das nicht zum Laufen bringen. Von einem schnellen Google sieht es so aus, als würde position: stickyes nicht mit Tabellenelementen funktionieren.
rjh

3
Die Bewerbung bei th hat für mich funktioniert: table thead tr th {...}
nurp

1
Sie müssen es auf das th anwenden, weil es nicht auf thead noch tr
helado

26

Ich habe ein Plugin geschrieben, das dies tut. Ich arbeite jetzt seit ungefähr einem Jahr daran und ich denke, es behandelt alle Eckfälle ziemlich gut:

  • Scrollen in einem Container mit Überlauf
  • innerhalb eines Fensters scrollen
  • Achten Sie darauf, was passiert, wenn Sie die Fenstergröße ändern
  • Halten Sie Ihre Ereignisse an den Header gebunden
  • Am wichtigsten ist jedoch, dass Sie nicht gezwungen werden, das CSS Ihrer Tabelle zu ändern , damit es funktioniert

Hier sind einige Demos / Dokumente:
http://mkoryak.github.io/floatThead/


großer Aufwand, funktioniert aber nicht mit IE 10 und hat einige Macken beim Ändern der Fenstergröße unter Firefox23 / Ubuntu.
Janning

2
Zu Ihrer Information: Ich habe die Probleme mit IE9 und 10 in der neuesten Version behoben.
Mkoryak

2
Können Sie eine Version erstellen, für die jQuery nicht erforderlich ist?
Curtis W

2
wahrscheinlich, weil er keine jquery verwendet ... und nein - ich werde keine Version erstellen, die keine jquery verwendet.
Mkoryak

1
Ich verwende ein einfaches jQery-Tablesorter-Plugin und gemäß Ihren FAQ mag Ihr Plugin die meisten CSS-Regeln wie #sortable td {..} und so nicht nicht. Ich habe versucht, ein wenig zu optimieren, aber ich konnte es nicht zum Laufen bringen.
Masche

25

Ich konnte das Problem mit dem Ändern der Spaltenbreite beheben. Ich begann mit Andrews obiger Lösung (vielen Dank!) Und fügte dann eine kleine Schleife hinzu, um die Breite der geklonten td's festzulegen:

$("#header-fixed td").each(function(index){
    var index2 = index;
    $(this).width(function(index2){
        return $("#table-1 td").eq(index).width();
    });
});

Dies löst das Problem, ohne den gesamten Tisch klonen und den Körper verstecken zu müssen. Ich bin brandneu in JavaScript und jQuery (und im Stapelüberlauf), daher sind Kommentare willkommen.


4
Hat gut funktioniert, aber ich musste die folgende Zeile hinzufügen $ ("# header-fixed"). Width ($ ("# table-1"). Width ()); damit die Spalten richtig ausgerichtet sind.
Ilya Fedotov

17

Dies ist bei weitem die beste Lösung, die ich für einen festen Tabellenkopf gefunden habe.

UPDATE 5/11: Fehler beim horizontalen Scrollen behoben, wie von Kerry Johnson hervorgehoben

Codepen: https://codepen.io/josephting/pen/demELL

;(function($) {
   $.fn.fixMe = function() {
      return this.each(function() {
         var $this = $(this),
            $t_fixed;
         function init() {
            $this.wrap('<div class="container" />');
            $t_fixed = $this.clone();
            $t_fixed.find("tbody").remove().end().addClass("fixed").insertBefore($this);
            resizeFixed();
         }
         function resizeFixed() {
           $t_fixed.width($this.outerWidth());
            $t_fixed.find("th").each(function(index) {
               $(this).css("width",$this.find("th").eq(index).outerWidth()+"px");
            });
         }
         function scrollFixed() {
            var offsetY = $(this).scrollTop(),
            offsetX = $(this).scrollLeft(),
            tableOffsetTop = $this.offset().top,
            tableOffsetBottom = tableOffsetTop + $this.height() - $this.find("thead").height(),
            tableOffsetLeft = $this.offset().left;
            if(offsetY < tableOffsetTop || offsetY > tableOffsetBottom)
               $t_fixed.hide();
            else if(offsetY >= tableOffsetTop && offsetY <= tableOffsetBottom && $t_fixed.is(":hidden"))
               $t_fixed.show();
            $t_fixed.css("left", tableOffsetLeft - offsetX + "px");
         }
         $(window).resize(resizeFixed);
         $(window).scroll(scrollFixed);
         init();
      });
   };
})(jQuery);

$(document).ready(function(){
   $("table").fixMe();
   $(".up").click(function() {
      $('html, body').animate({
      scrollTop: 0
   }, 2000);
 });
});
body{
  font:1.2em normal Arial,sans-serif;
  color:#34495E;
}

h1{
  text-align:center;
  text-transform:uppercase;
  letter-spacing:-2px;
  font-size:2.5em;
  margin:20px 0;
}

.container{
  width:90%;
  margin:auto;
}

table{
  border-collapse:collapse;
  width:100%;
}

.blue{
  border:2px solid #1ABC9C;
}

.blue thead{
  background:#1ABC9C;
}

.purple{
  border:2px solid #9B59B6;
}

.purple thead{
  background:#9B59B6;
}

thead{
  color:white;
}

th,td{
  text-align:center;
  padding:5px 0;
}

tbody tr:nth-child(even){
  background:#ECF0F1;
}

tbody tr:hover{
background:#BDC3C7;
  color:#FFFFFF;
}

.fixed{
  top:0;
  position:fixed;
  width:auto;
  display:none;
  border:none;
}

.scrollMore{
  margin-top:600px;
}

.up{
  cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>&darr; SCROLL &darr;</h1>
<table class="blue">
  <thead>
    <tr>
      <th>Colonne 1</th>
      <th>Colonne 2</th>
      <th>Colonne 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>MaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
  </tbody>
</table>

<h1 class="scrollMore">&darr; SCROLL MORE &darr;</h1>
<table class="purple">
  <thead>
    <tr>
      <th>Colonne 1</th>
      <th>Colonne 2</th>
      <th>Colonne 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
  </tbody>
</table>
<h1 class="up scrollMore">&uarr; UP &uarr;</h1>


Ich habe dieses Skript so korrigiert, dass es <th> -Elemente mit Rand und Abstand verarbeiten kann (andernfalls werden die festen <th> -Breiten des Headers zu breit eingestellt). Wechseln Sie einfach outerWidthzu widthin der Funktionsdefinition resizeFixed ().
Alanng

Möglicherweise müssen Sie einer z-indexpositiven Zahl in der .fixedKlasse auch eine CSS-Eigenschaft hinzufügen , damit Objekte, die nach dem Laden in die Tabelle gerendert wurden, beim Scrollen nicht über dem festen Header schweben.
Alanng

Einfach und nützlich.
RitchieD

wie man dynamisch mit der oberen Position umgeht. Angenommen, ich muss bis unter den Inhalt der festen Kopfzeile meiner Hauptseite scrollen. .fixed {top: 0;} .
VijayVishnu

2
@ KerryJohnson Danke für den Hinweis. Ich habe einige Änderungen vorgenommen, damit horizontales Scrollen und dynamische Spaltenbreiten unterstützt werden.
Josephphting

7

Die beste Lösung ist die Verwendung dieses JQuery-Plugins:

https://github.com/jmosbech/StickyTableHeaders

Dieses Plugin hat bei uns sehr gut funktioniert und wir haben viele andere Lösungen ausprobiert. Wir haben es in IE, Chrome und Firefox getestet


Kennen Sie eine Lösung, die auch die Funktionalität von Knockout-Daten-gebundenen Steuerelementen im Header beibehält?
Csaba Toth

Hat bei mir nicht funktioniert: Header befinden sich außerhalb der Tabelle und bleiben oben im Browser (Fenster), auch mit der Option "scrollableArea". Ich habe gesehen, dass dies zuvor ohne zusätzliche Kommentare erwähnt wurde. Vielleicht braucht es ein CSS, das er verwendet und das nicht verfügbar ist, damit es funktioniert.
Exel Gamboa

6

Hier gibt es schon viele wirklich gute Lösungen. Eine der einfachsten CSS-Lösungen, die ich in diesen Situationen verwende, lautet jedoch wie folgt:

table {
  /* Not required only for visualizing */
  border-collapse: collapse;
  width: 100%;
}

table thead tr th {
  /* Important */
  background-color: red;
  position: sticky;
  z-index: 100;
  top: 0;
}

td {
  /* Not required only for visualizing */
  padding: 1em;
}
<table>
  <thead>
    <tr>
      <th>Col1</th>
      <th>Col2</th>
      <th>Col3</th>
    </tr>
  </thead>
  <tbody>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
  </tbody>
</table>

Da kein JavaScript erforderlich ist, wird die Situation erheblich vereinfacht. Sie müssen sich im Wesentlichen auf die zweite CSS-Regel konzentrieren, die die Bedingungen enthält, um sicherzustellen, dass der Kopf der Tabelle unabhängig vom Bildlaufbereich oben bleibt.

Ausarbeitung der einzelnen Regeln im Detail. positionsoll dem Browser anzeigen, dass das Kopfobjekt, seine Zeile und seine Zellen alle oben bleiben müssen. Dies muss unbedingt begleitet sein top, was dem Browser angibt, dass der Kopf am oberen Rand der Seite oder des Ansichtsfensters haften bleibt. Darüber hinaus können Sie hinzufügen, z-indexum sicherzustellen, dass der Inhalt des Kopfes immer oben bleibt.

Die Hintergrundfarbe dient lediglich zur Veranschaulichung des Punktes. Sie müssen kein zusätzliches JavaScript verwenden, um diesen Effekt zu erzielen. Dies wird in den meisten gängigen Browsern nach 2016 unterstützt.


1
Imo der einfachen und saubersten Antwort gibt es immer einen einfachen Weg, um ein Problem zu lösen, dies ist der Fall. Obwohl ich ng-repeat mit anglejs verwende, funktioniert es wie ein Zauber.
David Castro

5

Ich habe eine einfache jQuery-Bibliothek namens Sticky Table Headers gefunden. Zwei Codezeilen und es hat genau das getan, was ich wollte. Die obigen Lösungen verwalten die Spaltenbreiten nicht. Wenn Sie also Tabellenzellen haben, die viel Platz beanspruchen, stimmt die resultierende Größe des persistenten Headers nicht mit der Breite Ihrer Tabelle überein.

http://plugins.jquery.com/StickyTableHeaders/

Nutzungsinformationen hier: https://github.com/jmosbech/StickyTableHeaders


3

Nachdem ich alle verfügbaren Lösungen überprüft hatte, schrieb ich ein Plugin, das jede Zeile (nicht nur die) oben auf der Seite oder im Container einfrieren kann. Es ist sehr einfach und sehr schnell. Fühlen Sie sich frei, es zu benutzen. http://maslianok.github.io/stickyRows/


3

Sie können diesen Ansatz verwenden, reines HTML und CSS, kein JS erforderlich :)

.table-fixed-header {
  display: flex;
  justify-content: space-between;
  margin-right: 18px
}

.table-fixed {
  display: flex;
  justify-content: space-between;
  height: 150px;
  overflow: scroll;
}

.column {
  flex-basis: 24%;
  border-radius: 5px;
  padding: 5px;
  text-align: center;
}
.column .title {
  border-bottom: 2px grey solid;
  border-top: 2px grey solid;
  text-align: center;
  display: block;
  font-weight: bold;
}

.cell {
  padding: 5px;
  border-right: 1px solid;
  border-left: 1px solid;
}

.cell:nth-of-type(even) {
  background-color: lightgrey;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Fixed header Bin</title>
</head>
<body>
<div class="table-fixed-header">
    
    <div class="column">
      <span class="title">col 1</span>
    </div>
    <div class="column">
      <span class="title">col 2</span>
    </div>
    <div class="column">
      <span class="title">col 3</span>
    </div>
    <div class="column">
      <span class="title">col 4</span>
    </div>
    
  </div>
  
  <div class="table-fixed">
    
    <div class="column">
      <div class="cell">alpha</div>
      <div class="cell">beta</div>
      <div class="cell">ceta</div>
    </div>
    
    <div class="column">
      <div class="cell">alpha</div>
      <div class="cell">beta</div>
      <div class="cell">ceta</div>
      <div class="cell">alpha</div>
      <div class="cell">beta</div>
      <div class="cell">ceta</div>
      <div class="cell">alpha</div>
      <div class="cell">beta</div>
      <div class="cell">ceta</div>
    </div>
    
    <div class="column">
      <div class="cell">alpha</div>
      <div class="cell">beta</div>
      <div class="cell">ceta</div>
      <div class="cell">beta</div>
      <div class="cell">beta</div>
      <div class="cell">beta</div>
      
    </div>
    
    <div class="column">
      <div class="cell">alpha</div>
      <div class="cell">beta</div>
      <div class="cell">ceta</div>
    </div>
    
  </div>
</body>
</html>


3

Ich habe eine einfache Lösung gefunden, ohne JQuery und nur CSS zu verwenden .

Sie müssen den festen Inhalt in 'th'-Tags einfügen und das CSS hinzufügen

table th {
    position:sticky;
    top:0;
    z-index:1;
    border-top:0;
    background: #ededed;
}
   

Die Eigenschaften position, z-index und top sind ausreichend. Sie können den Rest jedoch anwenden, um eine bessere Übersicht zu erhalten.


2

Ich hatte auch die gleichen Probleme mit der Randformatierung, die nicht mit Entrophys Code angezeigt wurde, sondern mit ein paar kleinen Korrekturen. Jetzt ist die Tabelle erweiterbar und zeigt alle CSS-Stilregeln an, die Sie hinzufügen können.

zu css hinzufügen:

#maintable{width: 100%}    

dann ist hier das neue Javascript:

    function moveScroll(){
    var scroll = $(window).scrollTop();
    var anchor_top = $("#maintable").offset().top;
    var anchor_bottom = $("#bottom_anchor").offset().top;
    if (scroll > anchor_top && scroll < anchor_bottom) {
        clone_table = $("#clone");
        if(clone_table.length === 0) {          
            clone_table = $("#maintable").clone();
            clone_table.attr({id: "clone"})
            .css({
                position: "fixed",
                "pointer-events": "none",
                 top:0
            })
            .width($("#maintable").width());

            $("#table-container").append(clone_table);
            // dont hide the whole table or you lose border style & 
            // actively match the inline width to the #maintable width if the 
            // container holding the table (window, iframe, div) changes width          
            $("#clone").width($("#maintable").width());
            // only the clone thead remains visible
            $("#clone thead").css({
                visibility:"visible"
            });
            // clone tbody is hidden
            $("#clone tbody").css({
                visibility:"hidden"
            });
            // add support for a tfoot element
            // and hide its cloned version too
            var footEl = $("#clone tfoot");
            if(footEl.length){
                footEl.css({
                    visibility:"hidden"
                });
            }
        }
    } 
    else {
        $("#clone").remove();
    }
}
$(window).scroll(moveScroll);

Dies funktioniert besser als die Entropie-Lösung, was die Randformatierung in der Kopfzeile betrifft. Im aktuellen Firefox (aber nicht in Chrome) werden jedoch nach Beginn des Bildlaufs sichtbare Artefakte am Zellenrand unterhalb der Tabelle erstellt.
Alanng

2

Hier ist eine Lösung, die auf der akzeptierten Antwort aufbaut. Es korrigiert: Spaltenbreiten, übereinstimmenden Tabellenstil und wenn die Tabelle in einem Container-Div gescrollt wird.

Verwendung

Stellen Sie sicher, dass Ihre Tabelle ein <thead>Tag hat, da nur der Inhalt des Kopfes repariert wird.

$("#header-fixed").fixHeader();

JavaSript

//Custom JQuery Plugin
(function ($) {
    $.fn.fixHeader = function () {
        return this.each(function () {
            var $table = $(this);
            var $sp = $table.scrollParent();
            var tableOffset = $table.position().top;
            var $tableFixed = $("<table />")
                .prop('class', $table.prop('class'))
                .css({ position: "fixed", "table-layout": "fixed", display: "none", "margin-top": "0px" });
            $table.before($tableFixed);
            $tableFixed.append($table.find("thead").clone());

            $sp.bind("scroll", function () {
                var offset = $(this).scrollTop();

                if (offset > tableOffset && $tableFixed.is(":hidden")) {
                    $tableFixed.show();
                    var p = $table.position();
                    var offset = $sp.offset();

                    //Set the left and width to match the source table and the top to match the scroll parent
                    $tableFixed.css({ left: p.left + "px", top: (offset ? offset.top : 0) + "px", }).width($table.width());

                    //Set the width of each column to match the source table
                    $.each($table.find('th, td'), function (i, th) {
                        $($tableFixed.find('th, td')[i]).width($(th).width());
                    });

                }
                else if (offset <= tableOffset && !$tableFixed.is(":hidden")) {
                    $tableFixed.hide();
                }
            });
        });
    };
})(jQuery);

1
Das hat bei mir gut funktioniert. Das einzige Problem sind Tabellen, die horizontal scrollen müssen. Ich habe hier ein Update in einer JSFiddle vorgenommen. Jsfiddle.net/4mgneob1/1 Ich subtrahiere, $sp.scrollLeft()wodurch der Betrag von links gescrollt wird, sodass beim Scrollen nach unten die feste Tabelle korrekt positioniert ist. Außerdem wurde beim horizontalen Scrollen überprüft, ob eine feste Tabelle sichtbar ist, um die linke Position anzupassen. Ein weiteres Problem, das ich nicht lösen konnte, ist, dass die feste Tabelle ausgeblendet wird, wenn die Tabelle über dem Ansichtsfenster liegt, bis der Benutzer einen Bildlauf nach oben durchführt.
Henesnarfel

1
GettingUncaught TypeError: $table.scrollParent is not a function
Karlingen

1

Dies hilft Ihnen dabei, einen festen Header zu haben, der auch horizontal mit Daten gescrollt werden kann.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Shubh</title>



<script type="text/javascript">
    var lastSeen = [ 0, 0 ];
    function checkScroll(div1, div2) {
        if (!div1 || !div2)
            return;
        var control = null;
        if (div1.scrollLeft != lastSeen[0])
            control = div1;
        else if (div2.scrollLeft != lastSeen[1])
            control = div2;
        if (control == null)
            return;
        else
            div1.scrollLeft = div2.scrollLeft = control.scrollLeft;
        lastSeen[0] = div1.scrollLeft;
        lastSeen[1] = div2.scrollLeft;
    }

    window
            .setInterval(
                    "checkScroll(document.getElementById('innertablediv'), document.getElementById('headertable'))",
                    1);
</script>

<style type="text/css">
#full {
    width: 400px;
    height: 300px;
}

#innertablediv {
    height: 200px;
    overflow: auto;
}

#headertable {
    overflow: hidden;
}
</style>
</head>
<body>

    <div id="full">




        <div id="headertable">
            <table border="1" bgcolor="grey" width="150px" id="headertable">
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>

                    <td>&nbsp;&nbsp;&nbsp;</td>
                </tr>

            </table>
        </div>




        <div id="innertablediv">

            <table border="1" id="innertableid">
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>

            </table>
        </div>
    </div>
</body>
</html>

Dies hilft Ihnen dabei, einen festen Header zu haben, der auch horizontal mit Daten gescrollt werden kann.
user2669926

1
function fix_table_header_position(){
 var width_list = [];
 $("th").each(function(){
    width_list.push($(this).width());
 });
 $("tr:first").css("position", "absolute");
 $("tr:first").css("z-index", "1000");
 $("th, td").each(function(index){
    $(this).width(width_list[index]);
 });

 $("tr:first").after("<tr height=" + $("tr:first").height() + "></tr>");}

Das ist meine Lösung


1

Ein bisschen spät zur Party, aber hier ist eine Implementierung, die mit mehreren Tabellen auf derselben Seite funktioniert und frei "ruckelt" (mit requestAnimationFrame). Es ist auch nicht erforderlich, eine Breite für die Spalten anzugeben. Das horizontale Scrollen funktioniert ebenfalls.

Die Überschriften sind in a definiert, divsodass Sie dort bei Bedarf Markups (wie Schaltflächen) hinzufügen können. Dies ist der gesamte HTML-Code, der benötigt wird:

<div class="tbl-resp">
  <table id="tbl1" class="tbl-resp__tbl">
     <thead>
      <tr>
        <th>col 1</th>
        <th>col 2</th>
        <th>col 3</th>
      </tr>
    </thead> 
  </table>
</div>

https://jsfiddle.net/lloydleo/bk5pt5gs/


1

In dieser Lösung wird ein fester Header dynamisch erstellt, der Inhalt und der Stil werden aus THEAD geklont

Alles was Sie brauchen sind zwei Zeilen zum Beispiel:

var $myfixedHeader = $("#Ttodo").FixedHeader(); //create fixed header $(window).scroll($myfixedHeader.moveScroll); //bind function to scroll event

Mein jquery Plugin FixedHeader und getStyleObject unten können Sie in die Datei .js einfügen

// JAVASCRIPT



/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 
Basic usage:
$.fn.copyCSS = function(source){
  var styles = $(source).getStyleObject();
  this.css(styles);
}
*/

(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            };
            style = window.getComputedStyle(dom, null);
            for(var i = 0, l = style.length; i < l; i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            };
            return returns;
        };
        if(style = dom.currentStyle){
            for(var prop in style){
                returns[prop] = style[prop];
            };
            return returns;
        };
        return this.css();
    }
})(jQuery);



   
//Floating Header of long table  PiotrC
(function ( $ ) {
    var tableTop,tableBottom,ClnH;
    $.fn.FixedHeader = function(){
        tableTop=this.offset().top,
        tableBottom=this.outerHeight()+tableTop;
        //Add Fixed header
        this.after('<table id="fixH"></table>');
        //Clone Header
        ClnH=$("#fixH").html(this.find("thead").clone());
        //set style
        ClnH.css({'position':'fixed', 'top':'0', 'zIndex':'60', 'display':'none',
        'border-collapse': this.css('border-collapse'),
		'border-spacing': this.css('border-spacing'),
        'margin-left': this.css('margin-left'),
        'width': this.css('width')            
        });
        //rewrite style cell of header
        $.each(this.find("thead>tr>th"), function(ind,val){
            $(ClnH.find('tr>th')[ind]).css($(val).getStyleObject());
        });
    return ClnH;}
    
    $.fn.moveScroll=function(){
        var offset = $(window).scrollTop();
        if (offset > tableTop && offset<tableBottom){
            if(ClnH.is(":hidden"))ClnH.show();
            $("#fixH").css('margin-left',"-"+$(window).scrollLeft()+"px");
        }
        else if (offset < tableTop || offset>tableBottom){
            if(!ClnH.is(':hidden'))ClnH.hide();
        }
    };
})( jQuery );





var $myfixedHeader = $("#repTb").FixedHeader();
$(window).scroll($myfixedHeader.moveScroll);
/* CSS - important only NOT transparent background */

#repTB{border-collapse: separate;border-spacing: 0;}

#repTb thead,#fixH thead{background: #e0e0e0 linear-gradient(#d8d8d8 0%, #e0e0e0 25%, #e0e0e0 75%, #d8d8d8 100%) repeat scroll 0 0;border:1px solid #CCCCCC;}

#repTb td{border:1px solid black}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


<h3>example</h3> 
<table id="repTb">
<thead>
<tr><th>Col1</th><th>Column2</th><th>Description</th></tr>
</thead>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
</table>


1

Erstellen Sie eine zusätzliche Tabelle mit demselben Header wie die Haupttabelle. Legen Sie einfach den Kopf in die neue Tabelle mit einer Zeile und allen Überschriften. Positionieren Sie absolut und Hintergrund weiß. Für die Haupttabelle setzen Sie es in ein div und verwenden Sie eine gewisse Höhe und Überlauf-y-Schriftrolle. Auf diese Weise wird unsere neue Tabelle den Header der Haupttabelle überwinden und dort bleiben. Umgib alles in einem div. Unten finden Sie den groben Code dafür.

      <div class="col-sm-8">

        <table id="header-fixed" class="table table-bordered table-hover" style="width: 351px;position: absolute;background: white;">
        <thead>
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th>Col3</th>
        </tr>
    </thead>
      </table>


    <div style="height: 300px;overflow-y: scroll;">
          <table id="tableMain" class="table table-bordered table-hover" style="table-layout:fixed;overflow-wrap: break-word;cursor:pointer">
<thead>
    <tr>
      <th>Col1</th>
      <th>Col2</th>
      <th>Col3</th>
    </tr>
  </thead>
  <tbody>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
  </tbody>

                                    </table>
              </div>
        </div>

1

div.wrapper {
    padding:20px;
}
table.scroll thead {
    width: 100%;
    background: #FC6822;
}
table.scroll thead tr:after {
    content: '';
    overflow-y: scroll;
    visibility: hidden;
}
table.scroll thead th {
    flex: 1 auto;
    display: block;
    color: #fff;
}
table.scroll tbody {
    display: block;
    width: 100%;
    overflow-y: auto;
    height: auto;
    max-height: 200px;
}
table.scroll thead tr,
table.scroll tbody tr {
    display: flex;
}
table.scroll tbody tr td {
    flex: 1 auto;
    word-wrap: break;
}
table.scroll thead tr th,
table.scroll tbody tr td {
    width: 25%;
    padding: 5px;
    text-align-left;
    border-bottom: 1px solid rgba(0,0,0,0.3);
}
<div class="wrapper">
    <table border="0" cellpadding="0" cellspacing="0" class="scroll">
        <thead>
            <tr>
                <th>Name</th>
                <th>Vorname</th>
                <th>Beruf</th>
                <th>Alter</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Müller</td>
                <td>Marie</td>
                <td>Künstlerin</td>
                <td>26</td>
            </tr>
            <tr>
                <td>Meier</td>
                <td>Stefan</td>
                <td>Chemiker</td>
                <td>52</td>
            </tr>
            <tr>
                <td>Schmidt</td>
                <td>Sabrine</td>
                <td>Studentin</td>
                <td>38</td>
            </tr>
            <tr>
                <td>Mustermann</td>
                <td>Max</td>
                <td>Lehrer</td>
                <td>41</td>
            </tr>
            <tr>
                <td>Müller</td>
                <td>Marie</td>
                <td>Künstlerin</td>
                <td>26</td>
            </tr>
            <tr>
                <td>Meier</td>
                <td>Stefan</td>
                <td>Chemiker</td>
                <td>52</td>
            </tr>
            <tr>
                <td>Schmidt</td>
                <td>Sabrine</td>
                <td>Studentin</td>
                <td>38</td>
            </tr>
            <tr>
                <td>Mustermann</td>
                <td>Max</td>
                <td>Lehrer</td>
                <td>41</td>
            </tr>
            <tr>
                <td>Müller</td>
                <td>Marie</td>
                <td>Künstlerin</td>
                <td>26</td>
            </tr>
            <tr>
                <td>Meier</td>
                <td>Stefan</td>
                <td>Chemiker</td>
                <td>52</td>
            </tr>
            <tr>
                <td>Schmidt</td>
                <td>Sabrine</td>
                <td>Studentin</td>
                <td>38</td>
            </tr>
            <tr>
                <td>Mustermann</td>
                <td>Max</td>
                <td>Lehrer</td>
                <td>41</td>
            </tr>
        </tbody>
    </table>
</div>

Demo: CSS- Demo mit festem Tabellenkopf


1

Beheben Sie Ihr Problem damit

tbody {
  display: table-caption;
  height: 200px;
  caption-side: bottom;
  overflow: auto;
}

0

Dies kann mithilfe der Stileigenschaftstransformation erreicht werden. Alles, was Sie tun müssen, ist, Ihre Tabelle in ein Div zu wickeln, dessen feste Höhe und Überlauf auf Auto eingestellt sind, zum Beispiel:

.tableWrapper {
  overflow: auto;
  height: calc( 100% - 10rem );
}

Und dann können Sie einen Onscroll-Handler anhängen. Hier haben Sie eine Methode, mit der jede Tabelle gefunden wird, die mit Folgendem verpackt ist <div class="tableWrapper"></div>:

  fixTables () {
    document.querySelectorAll('.tableWrapper').forEach((tableWrapper) => {
      tableWrapper.addEventListener('scroll', () => {
        var translate = 'translate(0,' + tableWrapper.scrollTop + 'px)'
        tableWrapper.querySelector('thead').style.transform = translate
      })
    })
  }

Und hier ist ein funktionierendes Beispiel dafür in Aktion (ich habe Bootstrap verwendet, um es schöner zu machen): Geige

Für diejenigen, die auch IE und Edge unterstützen möchten, ist hier der Ausschnitt:

  fixTables () {
    const tableWrappers = document.querySelectorAll('.tableWrapper')
    for (let i = 0, len = tableWrappers.length; i < len; i++) {
      tableWrappers[i].addEventListener('scroll', () => {
        const translate = 'translate(0,' + tableWrappers[i].scrollTop + 'px)'
        const headers = tableWrappers[i].querySelectorAll('thead th')
        for (let i = 0, len = headers.length; i < len; i++) {
          headers[i].style.transform = translate
        }
      })
    }
  }

In IE und Edge ist das Scrollen etwas verzögert ... aber es funktioniert

Hier ist eine Antwort, die mir hilft, dies herauszufinden: Antwort


0

Ich habe die meisten dieser Lösungen ausprobiert und schließlich (IMO) die beste, moderne Lösung gefunden:

CSS-Raster


Mit CSS-Grids können Sie ein 'Grid' definieren und schließlich eine schöne, javascriptfreie, browserübergreifende Lösung für eine Tabelle mit festem Header und scrollbarem Inhalt erstellen. Die Headerhöhe kann sogar dynamisch sein.

CSS : Als Raster anzeigen und die Anzahl festlegen template-rows:

.grid {
    display: grid;
    grid-template-rows: 50px auto; // For fixed height header
    grid-template-rows: auto auto; // For dynamic height header
}

HTML : Erstellen Sie einen Rastercontainer und die Anzahl der definierten rows:

<div class="grid">
    <div></div>
    <div></div>
</div>

Hier ist ein Arbeitsbeispiel:

CSS

body {
  margin: 0px;
  padding: 0px;
  text-align: center;
}

.table {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-rows: 50px auto;
}
.table-heading {
  background-color: #ddd;
}
.table-content {
  overflow-x: hidden;
  overflow-y: scroll;
}

HTML

<html>
    <head>
    </head>
    <body>
        <div class="table">
            <div class="table-heading">
                HEADING
            </div>
            <div class="table-content">
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
            </div>
        </div>
    </body>
</html>

0

Ich habe es mit Transformation versucht : übersetzen . Während es in Firefox und Chrome gut funktioniert, gibt es in IE11 einfach keine Funktion. Keine doppelten Bildlaufleisten. Unterstützt Tischfuß und Bildunterschrift. Reines Javascript, keine jQuery.

http://jsfiddle.net/wbLqzrfb/42/

thead.style.transform="translate(0,"+(dY-top-1)+"px)";

0

Ich habe eine Lösung ohne Abfrage gefunden

HTML

<table class="fixed_header">
  <thead>
    <tr>
      <th>Col 1</th>
      <th>Col 2</th>
      <th>Col 3</th>
      <th>Col 4</th>
      <th>Col 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>row 1-0</td>
      <td>row 1-1</td>
      <td>row 1-2</td>
      <td>row 1-3</td>
      <td>row 1-4</td>
    </tr>
    <tr>
      <td>row 2-0</td>
      <td>row 2-1</td>
      <td>row 2-2</td>
      <td>row 2-3</td>
      <td>row 2-4</td>
    </tr>
    <tr>
      <td>row 3-0</td>
      <td>row 3-1</td>
      <td>row 3-2</td>
      <td>row 3-3</td>
      <td>row 3-4</td>
    </tr>
    <tr>
      <td>row 4-0</td>
      <td>row 4-1</td>
      <td>row 4-2</td>
      <td>row 4-3</td>
      <td>row 4-4</td>
    </tr>
    <tr>
      <td>row 5-0</td>
      <td>row 5-1</td>
      <td>row 5-2</td>
      <td>row 5-3</td>
      <td>row 5-4</td>
    </tr>
    <tr>
      <td>row 6-0</td>
      <td>row 6-1</td>
      <td>row 6-2</td>
      <td>row 6-3</td>
      <td>row 6-4</td>
    </tr>
    <tr>
      <td>row 7-0</td>
      <td>row 7-1</td>
      <td>row 7-2</td>
      <td>row 7-3</td>
      <td>row 7-4</td>
    </tr>
  </tbody>
</table>

CSS

.fixed_header{
    width: 400px;
    table-layout: fixed;
    border-collapse: collapse;
}

.fixed_header tbody{
  display:block;
  width: 100%;
  overflow: auto;
  height: 100px;
}

.fixed_header thead tr {
   display: block;
}

.fixed_header thead {
  background: black;
  color:#fff;
}

.fixed_header th, .fixed_header td {
  padding: 5px;
  text-align: left;
  width: 200px;
}

Sie können es hier sehen: https://jsfiddle.net/lexsoul/fqbsty3h

Quelle: https://medium.com/@vembarrajan/html-css-tricks-scroll-able-table-body-tbody-d23182ae0fbc

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.