Tabela HTML ze stałymi nagłówkami?

Czy istnieje cross-browser CSS / JavaScript technika wyświetlania długiej tabeli HTML tak, że nagłówki kolumn pozostają stałe na ekranie i nie przewijają się wraz z ciałem tabeli. Pomyśl o efekcie "zamrożenia paneli" w programie Microsoft Excel.

Chcę móc przewijać zawartość tabeli, ale zawsze widzieć nagłówki kolumn u góry.

Author: Termininja, 2009-03-23

27 answers

Szukałem rozwiązania dla tego przez jakiś czas i okazało się, że większość odpowiedzi nie działa lub nie nadaje się do mojej sytuacji, więc napisałem proste rozwiązanie z jQuery.

Oto zarys rozwiązania:

  1. Klon tabeli, która musi mieć stały nagłówek, i umieścić sklonowana kopia na szczycie oryginału.
  2. usuń ciało tabeli z górnej tabeli.
  3. Usuń nagłówek tabeli z dolnej tabeli.
  4. Dostosuj szerokość kolumn. (Śledzimy oryginalne szerokości kolumn)

Poniżej znajduje się kod w uruchomionym demo.

function scrolify(tblAsJQueryObject, height) {
  var oTbl = tblAsJQueryObject;

  // for very large tables you can remove the four lines below
  // and wrap the table with <div> in the mark-up and assign
  // height and overflow property  
  var oTblDiv = $("<div/>");
  oTblDiv.css('height', height);
  oTblDiv.css('overflow', 'scroll');
  oTbl.wrap(oTblDiv);

  // save original width
  oTbl.attr("data-item-original-width", oTbl.width());
  oTbl.find('thead tr td').each(function() {
    $(this).attr("data-item-original-width", $(this).width());
  });
  oTbl.find('tbody tr:eq(0) td').each(function() {
    $(this).attr("data-item-original-width", $(this).width());
  });


  // clone the original table
  var newTbl = oTbl.clone();

  // remove table header from original table
  oTbl.find('thead tr').remove();
  // remove table body from new table
  newTbl.find('tbody tr').remove();

  oTbl.parent().parent().prepend(newTbl);
  newTbl.wrap("<div/>");

  // replace ORIGINAL COLUMN width				
  newTbl.width(newTbl.attr('data-item-original-width'));
  newTbl.find('thead tr td').each(function() {
    $(this).width($(this).attr("data-item-original-width"));
  });
  oTbl.width(oTbl.attr('data-item-original-width'));
  oTbl.find('tbody tr:eq(0) td').each(function() {
    $(this).width($(this).attr("data-item-original-width"));
  });
}

$(document).ready(function() {
  scrolify($('#tblNeedsScrolling'), 160); // 160 is height
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>

<div style="width:300px;border:6px green solid;">
  <table border="1" width="100%" id="tblNeedsScrolling">
    <thead>
      <tr><th>Header 1</th><th>Header 2</th></tr>
    </thead>
    <tbody>
      <tr><td>row 1, cell 1</td><td>row 1, cell 2</td></tr>
      <tr><td>row 2, cell 1</td><td>row 2, cell 2</td></tr>
      <tr><td>row 3, cell 1</td><td>row 3, cell 2</td></tr>
      <tr><td>row 4, cell 1</td><td>row 4, cell 2</td></tr>			
      <tr><td>row 5, cell 1</td><td>row 5, cell 2</td></tr>
      <tr><td>row 6, cell 1</td><td>row 6, cell 2</td></tr>
      <tr><td>row 7, cell 1</td><td>row 7, cell 2</td></tr>
      <tr><td>row 8, cell 1</td><td>row 8, cell 2</td></tr>			
    </tbody>
  </table>
</div>

To rozwiązanie działa w Chrome i IE. Ponieważ jest on oparty na jQuery, powinno to działać również w innych przeglądarkach obsługiwanych przez jQuery.

 82
Author: Mahes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-21 14:43:02

Można to rozwiązać w czterech liniach kodu.

Jeśli zależy Ci tylko na nowoczesnych przeglądarkach, stały nagłówek można znacznie łatwiej osiągnąć za pomocą przekształceń CSS. Brzmi dziwnie, ale działa świetnie:

  • HTML i CSS pozostają takie, jakie są.
  • brak zewnętrznych zależności JS.
  • 4 linijki kodu.
  • działa dla wszystkich konfiguracji (table-layout: fixed etc).
document.getElementById("wrap").addEventListener("scroll", function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});

Wsparcie dla transformacji CSS jest powszechnie dostępne z wyjątkiem IE8-. Oto pełny przykład dla odniesienia:

document.getElementById("wrap").addEventListener("scroll",function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});
/* your existing container */
#wrap {
    overflow: auto;
    height: 400px;
}

/* css for demo */
td {
    background-color: green;
    width: 200px;
    height: 100px;
}
<div id="wrap">
    <table>
        <thead>
            <tr>
                <th>Foo</th>
                <th>Bar</th>
            </tr>
        </thead>
        <tbody>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
        </tbody>
    </table>
</div>
 159
Author: Maximilian Hils,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-14 15:38:06

Właśnie zakończyłem układanie razem jQuery plugin, który będzie miał poprawną pojedynczą tabelę za pomocą poprawnego HTML (trzeba mieć thead i tbody) i wyświetli tabelę, która ma stałe nagłówki, opcjonalną stałą stopkę, która może być sklonowanym nagłówkiem lub dowolną zawartością, którą wybrałeś (paginacja, itp.). Jeśli chcesz skorzystać z większych monitorów, zmieni on również rozmiar tabeli po zmianie rozmiaru przeglądarki. Kolejną dodatkową funkcją jest możliwość przewijania bocznego, jeśli kolumny tabeli nie pasują do wszystkich widok.

Http://fixedheadertable.com/

Na GitHubie: http://markmalek.github.com/Fixed-Header-Table/

Jest niezwykle łatwy w konfiguracji i można tworzyć własne niestandardowe style dla niego. Używa również zaokrąglonych narożników we wszystkich przeglądarkach. Pamiętaj, że właśnie go wydałem, więc nadal jest technicznie beta i jest bardzo mało drobnych problemów, które prasuję.

Działa w przeglądarkach Internet Explorer 7, Internet Explorer 8, Safari, Firefox i Chrome.
 57
Author: Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 15:24:29

Stworzyłem również wtyczkę, która rozwiązuje ten problem. Mój projekt- jQuery.floatThead Istnieje już ponad rok i jest bardzo dojrzały.

Nie wymaga zewnętrznych stylów i nie oczekuje, że Twoja tabela będzie stylizowana w żaden szczególny sposób. Obsługuje IE8 + i FF / Chrome.

Obecnie (5/2018) posiada:

405 commitów i 998 gwiazdek na GitHubie


Wiele (nie wszystkie) odpowiedzi tutaj są szybkie hacki, które mogą rozwiązać problem jedna osoba miała, ale nie będzie działać na każdym stole.

Niektóre inne wtyczki są stare i prawdopodobnie działają świetnie z IE, ale pękną na FF i chrome.

 22
Author: mkoryak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-23 18:58:53

TL;DR

Jeśli kierujesz się nowoczesnymi przeglądarkami i nie masz ekstrawaganckich potrzeb stylistycznych: http://jsfiddle.net/dPixie/byB9d/3 / ... Chociaż wersja big four jest całkiem słodka, ta wersja znacznie lepiej radzi sobie z płynną szerokością.

Dobra wiadomość dla wszystkich!

Wraz z postępem HTML5 i CSS3 jest to teraz możliwe, przynajmniej dla nowoczesnych przeglądarek. Nieco hakerska implementacja, którą wymyśliłem, znajduje się tutaj: http://jsfiddle.net/dPixie/byB9d/3 / . testowałem go w FX 25, Chrome 31 i IE 10 ...

Odpowiedni HTML (Wstaw doctype HTML5 na górze dokumentu):

<section class="positioned">
  <div class="container">
    <table>
      <thead>
        <tr class="header">
          <th>
            Table attribute name
            <div>Table attribute name</div>
          </th>
          <th>
            Value
            <div>Value</div>
          </th>
          <th>
            Description
            <div>Description</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>align</td>
          <td>left, center, right</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
        </tr>
        <tr>
          <td>bgcolor</td>
          <td>rgb(x,x,x), #xxxxxx, colorname</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
        </tr>
        <tr>
          <td>border</td>
          <td>1,""</td>
          <td>Specifies whether the table cells should have borders or not</td>
        </tr>
        <tr>
          <td>cellpadding</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
        </tr>
        <tr>
          <td>cellspacing</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between cells</td>
        </tr>
        <tr>
          <td>frame</td>
          <td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
          <td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
        </tr>
        <tr>
          <td>rules</td>
          <td>none, groups, rows, cols, all</td>
          <td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
        </tr>
        <tr>
          <td>summary</td>
          <td>text</td>
          <td>Not supported in HTML5. Specifies a summary of the content of a table</td>
        </tr>
        <tr>
          <td>width</td>
          <td>pixels, %</td>
          <td>Not supported in HTML5. Specifies the width of a table</td>
        </tr>
      </tbody>
    </table>
  </div>
</section>

Z tym CSS:

html, body{
  margin:0;
  padding:0;
  height:100%;
}
section {
  position: relative;
  border: 1px solid #000;
  padding-top: 37px;
  background: #500;
}
section.positioned {
  position: absolute;
  top:100px;
  left:100px;
  width:800px;
  box-shadow: 0 0 15px #333;
}
.container {
  overflow-y: auto;
  height: 200px;
}
table {
  border-spacing: 0;
  width:100%;
}
td + td {
  border-left:1px solid #eee;
}
td, th {
  border-bottom:1px solid #eee;
  background: #ddd;
  color: #000;
  padding: 10px 25px;
}
th {
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}
th div{
  position: absolute;
  background: transparent;
  color: #fff;
  padding: 9px 25px;
  top: 0;
  margin-left: -25px;
  line-height: normal;
  border-left: 1px solid #800;
}
th:first-child div{
  border: none;
}
Ale jak?!

Po prostu masz nagłówek tabeli, który wizualnie ukrywasz, czyniąc go wysokim o 0px, który zawiera również divy używane jako stały nagłówek. Pojemnik stołu pozostawia wystarczająco dużo miejsca na górze, aby umożliwić absolutnie pozycjonowane nagłówek, a tabela z paskami przewijania wygląda tak, jak można się spodziewać.

Powyższy kod używa klasy pozycjonowanej do bezwzględnego pozycjonowania tabeli (używam jej w wyskakującym oknie dialogowym), ale możesz jej użyć również w przepływie dokumentu, usuwając klasę positioned z kontenera.

Ale ... To nie jest idealne. Firefox nie chce zrobić nagłówka 0px (przynajmniej nie znalazłem sposobu), ale uparcie utrzymuje go na minimum 4px ... Nie jest to wielki problem, ale w zależności od stylizacja będzie bałagan z granicami itp.

Tabela wykorzystuje również podejście faux column, gdzie kolor tła samego kontenera jest używany jako tło dla nagłówkowych divów, które są przezroczyste.

Podsumowanie

W sumie mogą wystąpić problemy ze stylizacją w zależności od twoich wymagań, zwłaszcza granic lub skomplikowanych tła. Mogą być też problemy z obliczalnością, nie sprawdzałem go jeszcze w wielu przeglądarkach (proszę o komentarz z Twoje doświadczenia, jeśli wypróbujesz), ale nie znalazłem niczego podobnego, więc pomyślałem, że warto opublikować ...

 20
Author: Jonas Schubert Erlandsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-18 09:37:30

Wszystkie próby rozwiązania tego spoza specyfikacji CSS są bladymi cieniami tego, czego naprawdę chcemy: dostawy na domniemanej obietnicy THEAD.

Ten problem z frozen-headers-for-a-table był otwarty w HTML / CSS przez długi czas.

W idealnym świecie, nie byłoby czystego css rozwiązanie dla tego problemu. Niestety nie wydaje się, aby był dobry na miejscu.

Odpowiednie standardy-dyskusje na ten temat obejmują:

UPDATE : Firefox wysłane stanowisko: sticky w wersji 32. Wszyscy wygrywają!

 19
Author: djsadinoff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-03 04:56:10

Oto wtyczka jQuery do stałego nagłówka tabeli. Umożliwia przewijanie całej strony, zamrażając nagłówek, gdy dotrze do góry. Działa dobrze ze stołami bootstrap na Twitterze.

Github repo: https://github.com/oma/table-fixed-header

Robi nie scroll tylko zawartość tabeli. Spójrz na inne narzędzia, aby to zrobić, jako jedna z tych innych odpowiedzi. Ty decydujesz, co najlepiej pasuje do twojej sprawy.

 14
Author: oma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-24 21:52:15

Większość zamieszczonych tu rozwiązań wymaga jQuery. Jeśli szukasz rozwiązania niezależnego od frameworka wypróbuj Grid: http://www.matts411.com/post/grid/

Jest hostowany na Githubie tutaj: https://github.com/mmurph211/Grid

Obsługuje nie tylko stałe nagłówki, ale także stałe lewe kolumny i stopki, między innymi.

 9
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-27 18:37:58

Bardziej dopracowana tabela przewijania czystego CSS

Wszystkie czyste rozwiązania CSS, które widziałem do tej pory-sprytne, choć mogą być-nie mają określonego poziomu polskiego, lub po prostu nie działają dobrze w niektórych sytuacjach. Więc postanowiłem stworzyć swój własny...

Cechy:

  • to czysty CSS, więc nie wymaga jQuery (ani żadnego javascript, do tego Materia)
  • możesz ustawić szerokość tabeli na procent (aka "fluid") lub stałą wartość, lub pozwolić zawartości określić jej szerokość (aka. "auto")
  • Szerokość kolumny może być również płynna, stała lub automatyczna.
  • kolumny nigdy nie zostaną wyrównane z nagłówkami z powodu poziomego przewijania (problem, który występuje w każdym innym rozwiązaniu opartym na CSS, które widziałem, które nie wymaga stałych szerokości).
  • kompatybilny ze wszystkimi popularnymi przeglądarkami desktopowymi, w tym Internet Explorerem powrót do wersji 8
  • czysty, dopracowany wygląd; brak niechlujnie wyglądających 1-pikselowych luk lub niewspółosiowych granic; wygląda tak samo we wszystkich przeglądarki

Oto kilka skrzypiec, które pokazują opcje płynnej i automatycznej szerokości:

  • Płynna szerokość i wysokość (dostosowuje się do rozmiaru ekranu): jsFiddle (należy pamiętać, że pasek przewijania pojawia się tylko wtedy, gdy jest potrzebny w tej konfiguracji, więc może być konieczne zmniejszenie ramki, aby go zobaczyć)

  • Automatyczna Szerokość, stała Wysokość (łatwiejsze do zintegrowania z innymi treściami): jsFiddle

Auto Szerokość, stała Wysokość konfiguracja prawdopodobnie ma więcej przypadków użycia, więc wyślę kod poniżej.

/*the following html and body rule sets are required only if using a % width or height*/
/*html {
  width: 100%;
  height: 100%;
}*/
body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /*if you want a fixed width, set it here, else set to auto*/
  min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
  height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
  min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 16px;
  line-height: 20px;
  padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
  text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /*this determines column header height*/
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /*header row background color*/
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
  max-height: 100%;
  overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
  overflow-x: hidden;
  border: 1px solid black; /*border around table body*/
}
.scrollingtable > div > div:after {background: white;} /*match page background color*/
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /*inverse of column header height*/
  /*margin-right: 17px;*/ /*uncomment if using % width*/
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /*match column header height*/
  padding-top: 1px;
  border-left: 1px solid black; /*borders between header cells*/
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /*inverse border-width*/
  background: white; /*match page background color*/
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /*inverse of border width*/
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /*match column header height*/
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"/></th>
            <th><div label="Column 2"/></th>
            <th><div label="Column 3"/></th>
            <th>
              <!--more versatile way of doing column label; requires 2 identical copies of label-->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->

Metoda, której użyłem do zamrożenia nagłówka jest podobna do D-Pixie, więc zapoznaj się z jego postem, aby uzyskać wyjaśnienie. Było mnóstwo błędów i ograniczeń z tą techniką, które można było naprawić tylko za pomocą sterty dodatkowych CSS i dodatkowego kontenera div lub dwóch.

 6
Author: DoctorDestructo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-15 12:59:04

Prosty plugin jQuery

Jest to odmiana rozwiązania Mahesa. Możesz to nazwać jak $('table#foo').scrollableTable();

Pomysł jest:

  • podziel thead i tbody na oddzielne table elementy
  • spraw, aby ich szerokość komórek ponownie pasowała
  • zawiń drugi table w div.scrollable
  • użyj CSS, aby {[7] } faktycznie przewijać

CSS może być:

div.scrollable { height: 300px; overflow-y: scroll;}

Caveats

  • oczywiście dzielenie tych tabel powoduje, że znaczniki są mniej semantyczne. Nie jestem pewien, jaki to ma wpływ na dostępność.
  • Ta wtyczka nie zajmuje się stopkami, wieloma nagłówkami itp.
  • testowałem go tylko w Chrome w wersji 20.

To powiedziawszy, to działa dla moich celów i jesteś wolny, aby wziąć i zmodyfikować go.

Oto plugin:

jQuery.fn.scrollableTable = function () {
  var $newTable, $oldTable, $scrollableDiv, originalWidths;
  $oldTable = $(this);

  // Once the tables are split, their cell widths may change. 
  // Grab these so we can make the two tables match again.
  originalWidths = $oldTable.find('tr:first td').map(function() {
    return $(this).width();
  });

  $newTable = $oldTable.clone();
  $oldTable.find('tbody').remove();
  $newTable.find('thead').remove();

  $.each([$oldTable, $newTable], function(index, $table) {
    $table.find('tr:first td').each(function(i) {
      $(this).width(originalWidths[i]);
    });
  });

  $scrollableDiv = $('<div/>').addClass('scrollable');
  $newTable.insertAfter($oldTable).wrap($scrollableDiv);
};
 5
Author: Nathan Long,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-05 15:23:45

:)

Nie tak czyste, ale czyste rozwiązanie HTML / CSS.

table {
    overflow-x:scroll;
}

tbody {
    max-height: /*your desired max height*/
    overflow-y:scroll;
    display:block;
}

Aktualizacja dla IE8+ jsfiddle przykład

 4
Author: Anton Matyulkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-19 19:40:24

Wsparcie dla stałej stopki

Rozszerzyłem funkcję Nathana, aby również obsługiwać stałą stopkę i maksymalną wysokość. Ponadto funkcja ustawi sam css, musisz tylko obsługiwać szerokość.

Użycie:

Stała Wysokość:

$('table').scrollableTable({ height: 100 });

Maksymalna wysokość (jeśli przeglądarka obsługuje opcję css 'max-height'):

$('table').scrollableTable({ maxHeight: 100 });

Skrypt:

jQuery.fn.scrollableTable = function(options) {

    var $originalTable, $headTable, $bodyTable, $footTable, $scrollableDiv, originalWidths;

    // prepare the separate parts of the table
    $originalTable = $(this);
    $headTable = $originalTable.clone();

    $headTable.find('tbody').remove();
    $headTable.find('tfoot').remove();

    $bodyTable = $originalTable.clone();
    $bodyTable.find('thead').remove();
    $bodyTable.find('tfoot').remove();

    $footTable = $originalTable.clone();
    $footTable.find('thead').remove();
    $footTable.find('tbody').remove();

    // grap original column widths and set them in the separate tables
    originalWidths = $originalTable.find('tr:first td').map(function() {
        return $(this).width();
    });

    $.each([$headTable, $bodyTable, $footTable], function(index, $table) {
        $table.find('tr:first td').each(function(i) {
            $(this).width(originalWidths[i]);
        });
    });

    // the div that makes the body table scroll
    $scrollableDiv = $('<div/>').css({
        'overflow-y': 'scroll'
    });

    if(options.height) {
        $scrollableDiv.css({'height': options.height});
    }
    else if(options.maxHeight) {
        $scrollableDiv.css({'max-height': options.maxHeight});
    }

    // add the new separate tables and remove the original one
    $headTable.insertAfter($originalTable);
    $bodyTable.insertAfter($headTable);
    $footTable.insertAfter($bodyTable);
    $bodyTable.wrap($scrollableDiv);
    $originalTable.remove();

};
 3
Author: gitaarik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-27 15:34:37

Dwa divy, jeden dla nagłówka, jeden dla danych. Przewijanie div danych i używanie JavaScript, aby ustawić szerokość kolumn w nagłówku na taką samą, jak szerokości w danych. Myślę, że szerokości kolumn danych muszą być stałe, a nie dynamiczne.

 2
Author: cjk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-20 18:57:13

Zdaję sobie sprawę, że pytanie pozwala JavaScript, ale tutaj jest czyste rozwiązanie CSS opracowałem, który pozwala również na tabeli, aby rozwinąć się poziomo. Testowane z IE10 oraz najnowszymi przeglądarkami Chrome i Firefox. Link do jsFiddle jest na dole.

HTML:

Putting some text here to differentiate between the header aligning with the top of the screen and the header aligning with the top of one of it's ancestor containers.
<div id="positioning-container">
<div id="scroll-container">
    <table>
        <colgroup>
            <col class="col1"></col>
            <col class="col2"></col>
        </colgroup>
        <thead>
            <th class="header-col1"><div>Header 1</div></th>
            <th class="header-col2"><div>Header 2</div></th>
        </thead>
        <tbody>
            <tr><td>Cell 1.1</td><td>Cell 1.2</td></tr>
            <tr><td>Cell 2.1</td><td>Cell 2.2</td></tr>
            <tr><td>Cell 3.1</td><td>Cell 3.2</td></tr>
            <tr><td>Cell 4.1</td><td>Cell 4.2</td></tr>
            <tr><td>Cell 5.1</td><td>Cell 5.2</td></tr>
            <tr><td>Cell 6.1</td><td>Cell 6.2</td></tr>
            <tr><td>Cell 7.1</td><td>Cell 7.2</td></tr>

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

I CSS:

table{
    border-collapse: collapse;
    table-layout: fixed;
    width: 100%;
}
/* Not required, just helps with alignment for this example */
td, th{
    padding: 0;
    margin: 0;
}

tbody{
    background-color: #ddf;
}

thead {
    /* Keeps the header in place. Don't forget top: 0 */
    position: absolute;
    top: 0;
    background-color: #ddd;
    /* The 17px is to adjust for the scrollbar width.
     * This is a new css value that makes this pure
     * css example possible */
    width: calc(100% - 17px);
    height: 20px;
}
/* Positioning container. Required to position the
 * header since the header uses position:absolute
 * (otherwise it would position at the top of the screen) */
#positioning-container{
    position: relative;
}
/* A container to set the scroll-bar and 
 * includes padding to move the table contents
 * down below the header (padding = header height) */
#scroll-container{
    overflow-y: auto;
    padding-top: 20px;
    height: 100px;
}
.header-col1{
    background-color: red;
}
/* fixed width header columns need a div to set their width */
.header-col1 div{
    width: 100px;
}
/* expandable columns need a width set on the th tag */
.header-col2{
    width: 100%;
}
.col1 {
    width: 100px;
}
.col2{
    width: 100%;
}

Http://jsfiddle.net/HNHRv/3/

 1
Author: bzuillsmith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 18:00:28

Dla tych, którzy próbowali ładne rozwiązanie podane przez Maximiliana Hilsa, i nie udało się go do pracy z Internet Explorer, miałem ten sam problem (IE 11) i dowiedział się, co było problemem.

W IE 11 transformacja stylu (przynajmniej z translate) nie działa na <THEAD>. Rozwiązałem to poprzez zastosowanie stylu do wszystkich <TH> W pętli. Zadziałało. Mój javascript wygląda tak

document.getElementById('pnlGridWrap').addEventListener("scroll", function () {
  var translate = "translate(0," + this.scrollTop + "px)";
  var myElements = this.querySelectorAll("th");
  for (var i = 0; i < myElements.length; i++) {
    myElements[i].style.transform=translate;
  }
});

W moim przypadku tabela była GridView w ASP.NET najpierw myślałem, że to ponieważ nie miał <THEAD>, ale nawet kiedy zmusiłem go do posiadania, to nie działało. Potem dowiedziałem się, co napisałem powyżej.

To bardzo ładne i proste rozwiązanie. Na Chrome jest idealny, na Firefoksie trochę jerky, a na IE jeszcze bardziej jerky. Ale w sumie dobre rozwiązanie.
 1
Author: Magnus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-19 16:02:50

Właściwość CSS position: sticky ma świetne wsparcie w większości nowoczesnych przeglądarek(miałem problemy z Edge, patrz poniżej).

To pozwala nam dość łatwo rozwiązać problem stałych nagłówków:

thead th { position: sticky; top: 0; }
Safari potrzebuje prefiksu dostawcy: -webkit-sticky.

Dla Firefoksa musiałem dodać min-height: 0 do jednego elementu nadrzędnego. Zapominam dokładnie, dlaczego to było potrzebne.

Większość niestety, implementacja Microsoft Edge wydaje się być tylko półdziałająca. Przynajmniej miałem trochę migotania i niewspółosiowego stołu komórki w moich testach. Stół był nadal użytkowy, ale miał istotne problemy estetyczne.

 1
Author: Daniel Waltrip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-04 01:37:11

Użyj najnowszej wersji jQuery i dołącz następujący kod javascript

$(window).scroll(function(){         
  $("id of the div element").offset({top:$(window).scrollTop()});         
}); 
 0
Author: Prabhavith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 19:00:01

Nie jest to dokładne rozwiązanie stałego wiersza nagłówka, ale stworzyłem dość pomysłową metodę powtarzania wiersza nagłówka w długiej tabeli, ale nadal zachowując możliwość sortowania. Ta niewielka opcja wymaga jQuery tablesorter plugin. Oto jak to działa:

Html

<table class="tablesorter boxlist" id="pmtable">
<thead class="fixedheader">
        <tr class="boxheadrow">
    <th width="70px" class="header">Job Number</th>
    <th width="10px" class="header">Pri</th>
    <th width="70px" class="header">CLLI</th>
    <th width="35px" class="header">Market</th>
    <th width="35px" class="header">Job Status</th>
    <th width="65px" class="header">Technology</th>
    <th width="95px;" class="header headerSortDown">MEI</th>
    <th width="95px" class="header">TEO Writer</th>
    <th width="75px" class="header">Quote Due</th>
    <th width="100px" class="header">Engineer</th>
    <th width="75px" class="header">ML Due</th>
    <th width="75px" class="header">ML Complete</th>
    <th width="75px" class="header">SPEC Due</th>
    <th width="75px" class="header">SPEC Complete</th>
    <th width="100px" class="header">Install Supervisor</th>
    <th width="75px" class="header">MasTec OJD</th>
    <th width="75px" class="header">Install Start</th>
    <th width="30px" class="header">Install Hours</th>
    <th width="75px" class="header">Revised CRCD</th>
    <th width="75px" class="header">Latest Ship-To-Site</th>
    <th width="30px" class="header">Total Parts</th>
    <th width="30px" class="header">OEM Rcvd</th>
    <th width="30px" class="header">Minor Rcvd</th>
    <th width="30px" class="header">Total Received</th>
    <th width="30px" class="header">% On Site</th>
    <th width="60px" class="header">Actions</th>
    </tr>
</thead>
<tbody class="scrollable">
        <tr data-job_id="3548" data-ml_id="" class="odd">
            <td class="c black">FL-8-RG9UP</td>
            <td data-pri="2" class="priority c yellow">M</td>
            <td class="c">FTLDFLOV</td>
            <td class="c">SFL</td>
            <td class="c">NOI</td>
            <td class="c">TRANSPORT</td>
            <td class="c"></td>
            <td class="c">Chris Byrd</td>
            <td class="c">Apr 13, 2013</td>
            <td class="c">Kris Hall</td>
            <td class="c">May 20, 2013</td>
            <td class="c">May 20, 2013</td>
            <td class="c">Jun 5, 2013</td>
            <td class="c">Jun 7, 2013</td>
            <td class="c">Joseph Fitz</td>
            <td class="c">Jun 10, 2013</td>
            <td class="c">TBD</td>
            <td class="c">123</td>
            <td class="c revised_crcd"><input readonly="true" name="revised_crcd" value="Jul 26, 2013" type="text" size="12" class="smInput r_crcd c hasDatepicker" id="dp1377194058616"></td>
            <td class="c">TBD</td>
            <td class="c">N/A</td>
            <td class="c">N/A</td>
            <td class="c">N/A</td>
            <td class="c">N/A</td>
            <td class="c">N/A</td>
            <td class="actions"><span style="float:left;" class="ui-icon ui-icon-folder-open editJob" title="View this job" s="" details'=""></span></td>
        </tr>
        <tr data-job_id="4264" data-ml_id="2959" class="even">
            <td class="c black">MTS13009SF</td>
            <td data-pri="2" class="priority c yellow">M</td>
            <td class="c">OJUSFLTL</td>
            <td class="c">SFL</td>
            <td class="c">NOI</td>
            <td class="c">TRANSPORT</td>
            <td class="c"></td>
            <td class="c">DeMarcus Stewart</td>
            <td class="c">May 22, 2013</td>
            <td class="c">Ryan Alsobrook</td>
            <td class="c">Jun 19, 2013</td>
            <td class="c">Jun 27, 2013</td>
            <td class="c">Jun 19, 2013</td>
            <td class="c">Jul 4, 2013</td>
            <td class="c">Randy Williams</td>
            <td class="c">Jun 21, 2013</td>
            <td class="c">TBD</td>
            <td class="c">95</td>
            <td class="c revised_crcd"><input readonly="true" name="revised_crcd" value="Aug 9, 2013" type="text" size="12" class="smInput r_crcd c hasDatepicker" id="dp1377194058632"></td><td class="c">TBD</td>
            <td class="c">0</td>
            <td class="c">0.00%</td>
            <td class="c">0.00%</td>
            <td class="c">0.00%</td>
            <td class="c">0.00%</td>
            <td class="actions"><span style="float:left;" class="ui-icon ui-icon-folder-open editJob" title="View this job" s="" details'=""></span><input style="float:left;" type="hidden" name="req_ship" class="reqShip hasDatepicker" id="dp1377194058464"><span style="float:left;" class="ui-icon ui-icon-calendar requestShip" title="Schedule this job for shipping"></span><span class="ui-icon ui-icon-info viewOrderInfo" style="float:left;" title="Show material details for this order"></span></td>
        </tr>
        .
        .
        .
        .
        <tr class="boxheadrow repeated-header">
        <th width="70px" class="header">Job Number</th>
    <th width="10px" class="header">Pri</th>
    <th width="70px" class="header">CLLI</th>
    <th width="35px" class="header">Market</th>
    <th width="35px" class="header">Job Status</th>
    <th width="65px" class="header">Technology</th>
    <th width="95px;" class="header">MEI</th>
    <th width="95px" class="header">TEO Writer</th>
    <th width="75px" class="header">Quote Due</th>
    <th width="100px" class="header">Engineer</th>
    <th width="75px" class="header">ML Due</th>
    <th width="75px" class="header">ML Complete</th>
    <th width="75px" class="header">SPEC Due</th>
    <th width="75px" class="header">SPEC Complete</th>
    <th width="100px" class="header">Install Supervisor</th>
    <th width="75px" class="header">MasTec OJD</th>
    <th width="75px" class="header">Install Start</th>
    <th width="30px" class="header">Install Hours</th>
    <th width="75px" class="header">Revised CRCD</th>
    <th width="75px" class="header">Latest Ship-To-Site</th>
    <th width="30px" class="header">Total Parts</th>
    <th width="30px" class="header">OEM Rcvd</th>
    <th width="30px" class="header">Minor Rcvd</th>
    <th width="30px" class="header">Total Received</th>
    <th width="30px" class="header">% On Site</th>
    <th width="60px" class="header">Actions</th>
    </tr>

Oczywiście, moja tabela ma o wiele więcej wierszy niż to. 193 aby być dokładnym, nakrętka możesz zobaczyć, gdzie powtarza się wiersz nagłówka. Powtarzający się wiersz nagłówka jest ustawiany przez to funkcja:

JQuery

    // clone the original header row and add the "repeated-header" class
var tblHeader = $('tr.boxheadrow').clone().addClass('repeated-header');
    // add the cloned header with the new class every 34th row (or as you see fit)
$('tbody tr:odd:nth-of-type(17n)').after(tblHeader);
    // on the 'sortStart' routine, remove all the inserted header rows
$('#pmtable').bind('sortStart', function() {
    $('.repeated-header').remove();
    // on the 'sortEnd' routine, add back all the header row lines.
}).bind('sortEnd', function() {
    $('tbody tr:odd:nth-of-type(17n)').after(tblHeader);
});
 0
Author: DevlshOne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 18:25:41

Żałuję, że wcześniej nie znalazłem rozwiązania @marka, ale poszedłem i napisałem własne, zanim zobaczyłem to pytanie...

Mine to bardzo lekka wtyczka jQuery, która obsługuje stały nagłówek, stopkę, rozpiętość kolumn( colspan), zmianę rozmiaru, poziome przewijanie i opcjonalną liczbę wierszy do wyświetlenia przed rozpoczęciem przewijania.

JQuery.scrollTableBody (GitHub)

Tak długo, jak masz stół z odpowiednim <thead>, <tbody>, i (opcjonalnie) <tfoot>, wszystko, co musisz zrobić, to to:

$('table').scrollTableBody();
 0
Author: Noah Heldman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 14:39:15

Opracowałem prostą, lekką wtyczkę jQuery do konwersji dobrze HTML tabeli do przewijalnej tabeli ze stałym nagłówkiem tabeli i kolumnami.

Wtyczka działa dobrze, aby dopasować piksel do piksela pozycjonowanie stałej sekcji z sekcją przewijalną. Dodatkowo możesz również zamrozić liczbę kolumn, które będą zawsze widoczne podczas przewijania w poziomie.

Demo i dokumentacja: http://meetselva.github.io/fixed-table-rows-cols/

Github Repo: https://github.com/meetselva/fixed-table-rows-cols

Poniżej jest użycie prostej tabeli ze stałym nagłówkiem,

$(<table selector>).fxdHdrCol({
    width:     "100%",
    height:    200,
    colModal: [{width: 30, align: 'center'},
               {width: 70, align: 'center'}, 
               {width: 200, align: 'left'}, 
               {width: 100, align: 'center'}, 
               {width: 70, align: 'center'}, 
               {width: 250, align: 'center'}
              ]
});
 0
Author: Selvakumar Arumugam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-12 17:07:35

Wydaje się, że wiele osób szuka tej odpowiedzi, znalazłem ją zakopaną w odpowiedzi na inne pytanie tutaj: Synchronizacja szerokości kolumn między tabelami w dwóch różnych ramkach itp

Z dziesiątek metod, które wypróbowałem, jest to jedyna metoda, którą znalazłem, która działa niezawodnie, aby umożliwić przewijanie dolnej tabeli z tabelą nagłówkową o tej samej szerokości.

Oto Jak to zrobiłem, najpierw poprawiłem na jsfiddle powyżej, aby utworzyć tę funkcję, która działa zarówno td, jak i th (w przypadku, gdy inni używają th do stylizacji swoich wierszy nagłówkowych).

var setHeaderTableWidth= function (headertableid,basetableid) {
            $("#"+headertableid).width($("#"+basetableid).width());
            $("#"+headertableid+" tr th").each(function (i) {
                $(this).width($($("#"+basetableid+" tr:first td")[i]).width());
            });
            $("#" + headertableid + " tr td").each(function (i) {
                $(this).width($($("#" + basetableid + " tr:first td")[i]).width());
            });
        }

Następnie musisz utworzyć dwie tabele, uwaga tabela nagłówkowa powinna mieć dodatkowy TD, aby pozostawić miejsce w górnej tabeli dla paska przewijania, jak to:

 <table id="headertable1" class="input-cells table-striped">
        <thead>
            <tr style="background-color:darkgray;color:white;"><th>header1</th><th>header2</th><th>header3</th><th>header4</th><th>header5</th><th>header6</th><th></th></tr>
        </thead>
     </table>
    <div id="resizeToBottom" style="overflow-y:scroll;overflow-x:hidden;">
        <table id="basetable1" class="input-cells table-striped">
            <tbody >
                <tr>
                    <td>testdata</td>
                    <td>2</td>
                    <td>3</td>
                    <td>4</span></td>
                    <td>55555555555555</td>
                    <td>test</td></tr>
            </tbody>
        </table>
    </div>

To zrób coś w stylu:

        setHeaderTableWidth('headertable1', 'basetable1');
        $(window).resize(function () {
            setHeaderTableWidth('headertable1', 'basetable1');
        });

Jest to jedyne rozwiązanie, które znalazłem na stackoverflow, które działa na wiele podobnych pytań, które zostały opublikowane, które działa we wszystkich moich przypadkach.

Na przykład próbowałem wtyczka jquery stickytables, która nie działa z durandal, a projekt Google code tutaj https://code.google.com/p/js-scroll-table-header/issues/detail?id=2

Inne rozwiązania polegające na klonowaniu tabel, mają słabą wydajność lub są do bani i nie działają we wszystkich przypadkach.

Nie ma potrzeby stosowania tych zbyt skomplikowanych rozwiązań, wystarczy zrobić dwie tabele takie jak poniższe przykłady i wywołać funkcję setHeaderTableWidth, jak opisano tutaj i BOOM, gotowe.

Jeśli to nie działa dla Ciebie, prawdopodobnie bawiłeś się swoją właściwością CSS box-sizing i musisz ją poprawnie ustawić. Łatwo jest zepsuć swój css przez przypadek, jest wiele rzeczy, które mogą pójść nie tak,więc po prostu bądź tego świadomy / ostrożny. TAKIE PODEJŚCIE DZIAŁA DLA MNIE. Jestem ciekaw, czy to działa na innych, daj mi znać. Powodzenia!

 0
Author: pilavdzice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:28

Oto rozwiązanie, z którym skończyliśmy pracować (aby poradzić sobie z niektórymi przypadkami krawędzi i starszymi wersjami IE ostatecznie również wyblakł pasek tytułowy na przewijaniu, a następnie zniknąć go z powrotem podczas przewijania kończy, ale w przeglądarkach Firefox i Webkit To rozwiązanie po prostu DZIAŁA . Zakłada border-collapse: collapse.

Kluczem do tego rozwiązania jest to, że po zastosowaniu border-collapse, CSS przekształca pracę nad nagłówkiem, więc to tylko kwestia przechwycenia przewijania zdarzenia i prawidłowe ustawienie transformacji. Nie musisz niczego powielać. Mimo że to zachowanie jest poprawnie zaimplementowane w przeglądarce, trudno sobie wyobrazić bardziej lekkie rozwiązanie.

JSFiddle: http://jsfiddle.net/podperson/tH9VU/2/

Jest zaimplementowany jako prosta wtyczka jQuery. Po prostu utwórz swój thead ' s lepki z wywołaniem takim jak $('thead').lepkie () i będą się kręcić. Działa dla wielu tabel na stronie i sekcji head w połowie wysokości stoły.

        $.fn.sticky = function(){
        $(this).each( function(){
            var thead = $(this),
                tbody = thead.next('tbody');

            updateHeaderPosition();

            function updateHeaderPosition(){
                if( 
                    thead.offset().top < $(document).scrollTop()
                    && tbody.offset().top + tbody.height() > $(document).scrollTop()
                ){
                    var tr = tbody.find('tr').last(),
                        y = tr.offset().top - thead.height() < $(document).scrollTop()
                            ? tr.offset().top - thead.height() - thead.offset().top
                            : $(document).scrollTop() - thead.offset().top;

                    thead.find('th').css({
                        'z-index': 100,
                        'transform': 'translateY(' + y + 'px)',
                        '-webkit-transform': 'translateY(' + y + 'px)'
                    });
                } else {
                    thead.find('th').css({
                        'transform': 'none',
                        '-webkit-transform': 'none'
                    });
                }
            }

            // see http://www.quirksmode.org/dom/events/scroll.html
            $(window).on('scroll', updateHeaderPosition);
        });
    }

    $('thead').sticky();
 0
Author: podperson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-07 16:45:40

Znalazłem to obejście-przenieś wiersz nagłówka w tabeli powyżej tabeli z danymi:

<html>
<head>
	<title>Fixed header</title>
	<style>
		table td {width:75px;}
	</style>
</head>

<body>
<div style="height:auto; width:350px; overflow:auto">
<table border="1">
<tr>
	<td>header 1</td>
	<td>header 2</td>
	<td>header 3</td>
</tr>
</table>
</div>

<div style="height:50px; width:350px; overflow:auto">
<table border="1">
<tr>
	<td>row 1 col 1</td>
	<td>row 1 col 2</td>
	<td>row 1 col 3</td>		
</tr>
<tr>
	<td>row 2 col 1</td>
	<td>row 2 col 2</td>
	<td>row 2 col 3</td>		
</tr>
<tr>
	<td>row 3 col 1</td>
	<td>row 3 col 2</td>
	<td>row 3 col 3</td>		
</tr>
<tr>
	<td>row 4 col 1</td>
	<td>row 4 col 2</td>
	<td>row 4 col 3</td>		
</tr>
<tr>
	<td>row 5 col 1</td>
	<td>row 5 col 2</td>
	<td>row 5 col 3</td>		
</tr>
<tr>
	<td>row 6 col 1</td>
	<td>row 6 col 2</td>
	<td>row 6 col 3</td>		
</tr>
</table>
</div>


</body>
</html>
 0
Author: Leonid Alzhin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-21 18:19:09

Poprzez zastosowanie wtyczki stickytableheaders jQuery do tabeli, nagłówki kolumn zostaną przyklejone do górnej części widoku podczas przewijania w dół.

Przykład:

$(function () {
    $("table").stickyTableHeaders();
});

/*! Copyright (c) 2011 by Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders
	MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */

;
(function ($, window, undefined) {
    'use strict';

    var name = 'stickyTableHeaders',
        id = 0,
        defaults = {
            fixedOffset: 0,
            leftOffset: 0,
            marginTop: 0,
            scrollableArea: window
        };

    function Plugin(el, options) {
        // To avoid scope issues, use 'base' instead of 'this'
        // to reference this class from internal events and functions.
        var base = this;

        // Access to jQuery and DOM versions of element
        base.$el = $(el);
        base.el = el;
        base.id = id++;
        base.$window = $(window);
        base.$document = $(document);

        // Listen for destroyed, call teardown
        base.$el.bind('destroyed',
        $.proxy(base.teardown, base));

        // Cache DOM refs for performance reasons
        base.$clonedHeader = null;
        base.$originalHeader = null;

        // Keep track of state
        base.isSticky = false;
        base.hasBeenSticky = false;
        base.leftOffset = null;
        base.topOffset = null;

        base.init = function () {
            base.$el.each(function () {
                var $this = $(this);

                // remove padding on <table> to fix issue #7
                $this.css('padding', 0);

                base.$originalHeader = $('thead:first', this);
                base.$clonedHeader = base.$originalHeader.clone();
                $this.trigger('clonedHeader.' + name, [base.$clonedHeader]);

                base.$clonedHeader.addClass('tableFloatingHeader');
                base.$clonedHeader.css('display', 'none');

                base.$originalHeader.addClass('tableFloatingHeaderOriginal');

                base.$originalHeader.after(base.$clonedHeader);

                base.$printStyle = $('<style type="text/css" media="print">' +
                    '.tableFloatingHeader{display:none !important;}' +
                    '.tableFloatingHeaderOriginal{position:static !important;}' +
                    '</style>');
                $('head').append(base.$printStyle);
            });

            base.setOptions(options);
            base.updateWidth();
            base.toggleHeaders();
            base.bind();
        };

        base.destroy = function () {
            base.$el.unbind('destroyed', base.teardown);
            base.teardown();
        };

        base.teardown = function () {
            if (base.isSticky) {
                base.$originalHeader.css('position', 'static');
            }
            $.removeData(base.el, 'plugin_' + name);
            base.unbind();

            base.$clonedHeader.remove();
            base.$originalHeader.removeClass('tableFloatingHeaderOriginal');
            base.$originalHeader.css('visibility', 'visible');
            base.$printStyle.remove();

            base.el = null;
            base.$el = null;
        };

        base.bind = function () {
            base.$scrollableArea.on('scroll.' + name, base.toggleHeaders);
            if (!base.isWindowScrolling) {
                base.$window.on('scroll.' + name + base.id, base.setPositionValues);
                base.$window.on('resize.' + name + base.id, base.toggleHeaders);
            }
            base.$scrollableArea.on('resize.' + name, base.toggleHeaders);
            base.$scrollableArea.on('resize.' + name, base.updateWidth);
        };

        base.unbind = function () {
            // unbind window events by specifying handle so we don't remove too much
            base.$scrollableArea.off('.' + name, base.toggleHeaders);
            if (!base.isWindowScrolling) {
                base.$window.off('.' + name + base.id, base.setPositionValues);
                base.$window.off('.' + name + base.id, base.toggleHeaders);
            }
            base.$scrollableArea.off('.' + name, base.updateWidth);
        };

        base.toggleHeaders = function () {
            if (base.$el) {
                base.$el.each(function () {
                    var $this = $(this),
                        newLeft,
                        newTopOffset = base.isWindowScrolling ? (
                        isNaN(base.options.fixedOffset) ? base.options.fixedOffset.outerHeight() : base.options.fixedOffset) : base.$scrollableArea.offset().top + (!isNaN(base.options.fixedOffset) ? base.options.fixedOffset : 0),
                        offset = $this.offset(),

                        scrollTop = base.$scrollableArea.scrollTop() + newTopOffset,
                        scrollLeft = base.$scrollableArea.scrollLeft(),

                        scrolledPastTop = base.isWindowScrolling ? scrollTop > offset.top : newTopOffset > offset.top,
                        notScrolledPastBottom = (base.isWindowScrolling ? scrollTop : 0) < (offset.top + $this.height() - base.$clonedHeader.height() - (base.isWindowScrolling ? 0 : newTopOffset));

                    if (scrolledPastTop && notScrolledPastBottom) {
                        newLeft = offset.left - scrollLeft + base.options.leftOffset;
                        base.$originalHeader.css({
                            'position': 'fixed',
                                'margin-top': base.options.marginTop,
                                'left': newLeft,
                                'z-index': 3 // #18: opacity bug
                        });
                        base.leftOffset = newLeft;
                        base.topOffset = newTopOffset;
                        base.$clonedHeader.css('display', '');
                        if (!base.isSticky) {
                            base.isSticky = true;
                            // make sure the width is correct: the user might have resized the browser while in static mode
                            base.updateWidth();
                        }
                        base.setPositionValues();
                    } else if (base.isSticky) {
                        base.$originalHeader.css('position', 'static');
                        base.$clonedHeader.css('display', 'none');
                        base.isSticky = false;
                        base.resetWidth($('td,th', base.$clonedHeader), $('td,th', base.$originalHeader));
                    }
                });
            }
        };

        base.setPositionValues = function () {
            var winScrollTop = base.$window.scrollTop(),
                winScrollLeft = base.$window.scrollLeft();
            if (!base.isSticky || winScrollTop < 0 || winScrollTop + base.$window.height() > base.$document.height() || winScrollLeft < 0 || winScrollLeft + base.$window.width() > base.$document.width()) {
                return;
            }
            base.$originalHeader.css({
                'top': base.topOffset - (base.isWindowScrolling ? 0 : winScrollTop),
                    'left': base.leftOffset - (base.isWindowScrolling ? 0 : winScrollLeft)
            });
        };

        base.updateWidth = function () {
            if (!base.isSticky) {
                return;
            }
            // Copy cell widths from clone
            if (!base.$originalHeaderCells) {
                base.$originalHeaderCells = $('th,td', base.$originalHeader);
            }
            if (!base.$clonedHeaderCells) {
                base.$clonedHeaderCells = $('th,td', base.$clonedHeader);
            }
            var cellWidths = base.getWidth(base.$clonedHeaderCells);
            base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells);

            // Copy row width from whole table
            base.$originalHeader.css('width', base.$clonedHeader.width());
        };

        base.getWidth = function ($clonedHeaders) {
            var widths = [];
            $clonedHeaders.each(function (index) {
                var width, $this = $(this);

                if ($this.css('box-sizing') === 'border-box') {
                    width = $this[0].getBoundingClientRect().width; // #39: border-box bug
                } else {
                    var $origTh = $('th', base.$originalHeader);
                    if ($origTh.css('border-collapse') === 'collapse') {
                        if (window.getComputedStyle) {
                            width = parseFloat(window.getComputedStyle(this, null).width);
                        } else {
                            // ie8 only
                            var leftPadding = parseFloat($this.css('padding-left'));
                            var rightPadding = parseFloat($this.css('padding-right'));
                            // Needs more investigation - this is assuming constant border around this cell and it's neighbours.
                            var border = parseFloat($this.css('border-width'));
                            width = $this.outerWidth() - leftPadding - rightPadding - border;
                        }
                    } else {
                        width = $this.width();
                    }
                }

                widths[index] = width;
            });
            return widths;
        };

        base.setWidth = function (widths, $clonedHeaders, $origHeaders) {
            $clonedHeaders.each(function (index) {
                var width = widths[index];
                $origHeaders.eq(index).css({
                    'min-width': width,
                        'max-width': width
                });
            });
        };

        base.resetWidth = function ($clonedHeaders, $origHeaders) {
            $clonedHeaders.each(function (index) {
                var $this = $(this);
                $origHeaders.eq(index).css({
                    'min-width': $this.css('min-width'),
                        'max-width': $this.css('max-width')
                });
            });
        };

        base.setOptions = function (options) {
            base.options = $.extend({}, defaults, options);
            base.$scrollableArea = $(base.options.scrollableArea);
            base.isWindowScrolling = base.$scrollableArea[0] === window;
        };

        base.updateOptions = function (options) {
            base.setOptions(options);
            // scrollableArea might have changed
            base.unbind();
            base.bind();
            base.updateWidth();
            base.toggleHeaders();
        };

        // Run initializer
        base.init();
    }

    // A plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[name] = function (options) {
        return this.each(function () {
            var instance = $.data(this, 'plugin_' + name);
            if (instance) {
                if (typeof options === 'string') {
                    instance[options].apply(instance);
                } else {
                    instance.updateOptions(options);
                }
            } else if (options !== 'destroy') {
                $.data(this, 'plugin_' + name, new Plugin(this, options));
            }
        });
    };

})(jQuery, window);
body {
    margin: 0 auto;
    padding: 0 20px;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 11px;
    color: #555;
}
table {
    border: 0;
    padding: 0;
    margin: 0 0 20px 0;
    border-collapse: collapse;
}
th {
    padding: 5px;
    /* NOTE: th padding must be set explicitly in order to support IE */
    text-align: right;
    font-weight:bold;
    line-height: 2em;
    color: #FFF;
    background-color: #555;
}
tbody td {
    padding: 10px;
    line-height: 18px;
    border-top: 1px solid #E0E0E0;
}
tbody tr:nth-child(2n) {
    background-color: #F7F7F7;
}
tbody tr:hover {
    background-color: #EEEEEE;
}
td {
    text-align: right;
}
td:first-child, th:first-child {
    text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div style="width:3000px">some really really wide content goes here</div>
<table>
    <thead>
        <tr>
            <th colspan="9">Companies listed on NASDAQ OMX Copenhagen.</th>
        </tr>
        <tr>
            <th>Full name</th>
            <th>CCY</th>
            <th>Last</th>
            <th>+/-</th>
            <th>%</th>
            <th>Bid</th>
            <th>Ask</th>
            <th>Volume</th>
            <th>Turnover</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>A.P. Møller...</td>
            <td>DKK</td>
            <td>33,220.00</td>
            <td>760</td>
            <td>2.34</td>
            <td>33,140.00</td>
            <td>33,220.00</td>
            <td>594</td>
            <td>19,791,910</td>
        </tr>
        <tr>
            <td>A.P. Møller...</td>
            <td>DKK</td>
            <td>34,620.00</td>
            <td>640</td>
            <td>1.88</td>
            <td>34,620.00</td>
            <td>34,700.00</td>
            <td>9,954</td>
            <td>346,530,246</td>
        </tr>
        <tr>
            <td>Carlsberg A</td>
            <td>DKK</td>
            <td>380</td>
            <td>0</td>
            <td>0</td>
            <td>371</td>
            <td>391.5</td>
            <td>6</td>
            <td>2,280</td>
        </tr>
        <tr>
            <td>Carlsberg B</td>
            <td>DKK</td>
            <td>364.4</td>
            <td>8.6</td>
            <td>2.42</td>
            <td>363</td>
            <td>364.4</td>
            <td>636,267</td>
            <td>228,530,601</td>
        </tr>
        <tr>
            <td>Chr. Hansen...</td>
            <td>DKK</td>
            <td>114.5</td>
            <td>-1.6</td>
            <td>-1.38</td>
            <td>114.2</td>
            <td>114.5</td>
            <td>141,822</td>
            <td>16,311,454</td>
        </tr>
        <tr>
            <td>Coloplast B</td>
            <td>DKK</td>
            <td>809.5</td>
            <td>11</td>
            <td>1.38</td>
            <td>809</td>
            <td>809.5</td>
            <td>85,840</td>
            <td>69,363,301</td>
        </tr>
        <tr>
            <td>D/S Norden</td>
            <td>DKK</td>
            <td>155</td>
            <td>-1.5</td>
            <td>-0.96</td>
            <td>155</td>
            <td>155.1</td>
            <td>51,681</td>
            <td>8,037,225</td>
        </tr>
        <tr>
            <td>Danske Bank</td>
            <td>DKK</td>
            <td>69.05</td>
            <td>2.55</td>
            <td>3.83</td>
            <td>69.05</td>
            <td>69.2</td>
            <td>1,723,719</td>
            <td>115,348,068</td>
        </tr>
        <tr>
            <td>DSV</td>
            <td>DKK</td>
            <td>105.4</td>
            <td>0.2</td>
            <td>0.19</td>
            <td>105.2</td>
            <td>105.4</td>
            <td>674,873</td>
            <td>71,575,035</td>
        </tr>
        <tr>
            <td>FLSmidth &amp; Co.</td>
            <td>DKK</td>
            <td>295.8</td>
            <td>-1.8</td>
            <td>-0.6</td>
            <td>295.1</td>
            <td>295.8</td>
            <td>341,263</td>
            <td>100,301,032</td>
        </tr>
        <tr>
            <td>G4S plc</td>
            <td>DKK</td>
            <td>22.53</td>
            <td>0.05</td>
            <td>0.22</td>
            <td>22.53</td>
            <td>22.57</td>
            <td>190,920</td>
            <td>4,338,150</td>
        </tr>
        <tr>
            <td>Jyske Bank</td>
            <td>DKK</td>
            <td>144.2</td>
            <td>1.4</td>
            <td>0.98</td>
            <td>142.8</td>
            <td>144.2</td>
            <td>78,163</td>
            <td>11,104,874</td>
        </tr>
        <tr>
            <td>Københavns ...</td>
            <td>DKK</td>
            <td>1,580.00</td>
            <td>-12</td>
            <td>-0.75</td>
            <td>1,590.00</td>
            <td>1,620.00</td>
            <td>82</td>
            <td>131,110</td>
        </tr>
        <tr>
            <td>Lundbeck</td>
            <td>DKK</td>
            <td>103.4</td>
            <td>-2.5</td>
            <td>-2.36</td>
            <td>103.4</td>
            <td>103.8</td>
            <td>157,162</td>
            <td>16,462,282</td>
        </tr>
        <tr>
            <td>Nordea Bank</td>
            <td>DKK</td>
            <td>43.22</td>
            <td>-0.06</td>
            <td>-0.14</td>
            <td>43.22</td>
            <td>43.25</td>
            <td>167,520</td>
            <td>7,310,143</td>
        </tr>
        <tr>
            <td>Novo Nordisk B</td>
            <td>DKK</td>
            <td>552.5</td>
            <td>-3.5</td>
            <td>-0.63</td>
            <td>550.5</td>
            <td>552.5</td>
            <td>843,533</td>
            <td>463,962,375</td>
        </tr>
        <tr>
            <td>Novozymes B</td>
            <td>DKK</td>
            <td>805.5</td>
            <td>5.5</td>
            <td>0.69</td>
            <td>805</td>
            <td>805.5</td>
            <td>152,188</td>
            <td>121,746,199</td>
        </tr>
        <tr>
            <td>Pandora</td>
            <td>DKK</td>
            <td>39.04</td>
            <td>0.94</td>
            <td>2.47</td>
            <td>38.8</td>
            <td>39.04</td>
            <td>350,965</td>
            <td>13,611,838</td>
        </tr>
        <tr>
            <td>Rockwool In...</td>
            <td>DKK</td>
            <td>492</td>
            <td>0</td>
            <td>0</td>
            <td>482</td>
            <td>492</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Rockwool In...</td>
            <td>DKK</td>
            <td>468</td>
            <td>12</td>
            <td>2.63</td>
            <td>465.2</td>
            <td>468</td>
            <td>9,885</td>
            <td>4,623,850</td>
        </tr>
        <tr>
            <td>Sydbank</td>
            <td>DKK</td>
            <td>95</td>
            <td>0.05</td>
            <td>0.05</td>
            <td>94.7</td>
            <td>95</td>
            <td>103,438</td>
            <td>9,802,899</td>
        </tr>
        <tr>
            <td>TDC</td>
            <td>DKK</td>
            <td>43.6</td>
            <td>0.13</td>
            <td>0.3</td>
            <td>43.5</td>
            <td>43.6</td>
            <td>845,110</td>
            <td>36,785,339</td>
        </tr>
        <tr>
            <td>Topdanmark</td>
            <td>DKK</td>
            <td>854</td>
            <td>13.5</td>
            <td>1.61</td>
            <td>854</td>
            <td>855</td>
            <td>38,679</td>
            <td>32,737,678</td>
        </tr>
        <tr>
            <td>Tryg</td>
            <td>DKK</td>
            <td>290.4</td>
            <td>0.3</td>
            <td>0.1</td>
            <td>290</td>
            <td>290.4</td>
            <td>94,587</td>
            <td>27,537,247</td>
        </tr>
        <tr>
            <td>Vestas Wind...</td>
            <td>DKK</td>
            <td>90.15</td>
            <td>-4.2</td>
            <td>-4.45</td>
            <td>90.1</td>
            <td>90.15</td>
            <td>1,317,313</td>
            <td>121,064,314</td>
        </tr>
        <tr>
            <td>William Dem...</td>
            <td>DKK</td>
            <td>417.6</td>
            <td>0.1</td>
            <td>0.02</td>
            <td>417</td>
            <td>417.6</td>
            <td>64,242</td>
            <td>26,859,554</td>
        </tr>
    </tbody>
</table>
<div style="height: 4000px">lots of content down here...</div>
 0
Author: shilovk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 15:47:23

Oto poprawiona odpowiedź na tę zamieszczoną przez Maximilian Hils .

Ten działa w IE11 bez migotania:

var headerCells = tableWrap.querySelectorAll("thead td");
for (var i = 0; i < headerCells.length; i++) {
    var headerCell = headerCells[i];
    headerCell.style.backgroundColor = "silver";
}
var lastSTop = tableWrap.scrollTop;
tableWrap.addEventListener("scroll", function () {
    var stop = this.scrollTop;
    if (stop < lastSTop) {
        // reseting the transform for the scrolling up to hide the headers
        for (var i = 0; i < headerCells.length; i++) {
            headerCells[i].style.transitionDelay = "0s";
            headerCells[i].style.transform = "";
        }
    }
    lastSTop = stop;
    var translate = "translate(0," + stop + "px)";
    for (var i = 0; i < headerCells.length; i++) {
        headerCells[i].style.transitionDelay = "0.25s";
        headerCells[i].style.transform = translate;
    }
});
 0
Author: user4617883,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-29 15:23:39

LubięMaximillian Hils' odpowiedz, ale miałem kilka problemów:

  1. transformacja nie działa w Edge lub IE, chyba że zastosujesz ją do th
  2. nagłówek migocze podczas przewijania w Edge i IE
  3. moja tabela jest ładowana za pomocą ajax, więc chciałem dołączyć do zdarzenia przewijania okna zamiast zdarzenia przewijania owijarki

Aby pozbyć się migotania, używam timeoutu, aby poczekać, aż Użytkownik skończy przewijanie, a następnie zastosować transformację - tak nagłówek nie jest widoczny podczas przewijania.

Napisałem to również używając jQuery, jedną z zalet tego jest to, że jQuery powinien obsługiwać przedrostki dostawcy dla Ciebie

    var isScrolling, lastTop, lastLeft, isLeftHidden, isTopHidden;

    //Scroll events don't bubble https://stackoverflow.com/a/19375645/150342
    //so can't use $(document).on("scroll", ".table-container-fixed", function (e) {
    document.addEventListener('scroll', function (event) {
        var $container = $(event.target);
        if (!$container.hasClass("table-container-fixed"))
            return;    

        //transform needs to be applied to th for Edge and IE
        //in this example I am also fixing the leftmost column
        var $topLeftCell = $container.find('table:first > thead > tr > th:first');
        var $headerCells = $topLeftCell.siblings();
        var $columnCells = $container
           .find('table:first > tbody > tr > td:first-child, ' +
                 'table:first > tfoot > tr > td:first-child');

        //hide the cells while returning otherwise they show on top of the data
        if (!isLeftHidden) {
            var currentLeft = $container.scrollLeft();
            if (currentLeft < lastLeft) {
                //scrolling left
                isLeftHidden = true;
                $topLeftCell.css('visibility', 'hidden');
                $columnCells.css('visibility', 'hidden');
            }
            lastLeft = currentLeft;
        }

        if (!isTopHidden) {
            var currentTop = $container.scrollTop();
            if (currentTop < lastTop) {
                //scrolling up
                isTopHidden = true;
                $topLeftCell.css('visibility', 'hidden');
                $headerCells.css('visibility', 'hidden');
            }
            lastTop = currentTop;
        }

        // Using timeout to delay transform until user stops scrolling
        // Clear timeout while scrolling
        window.clearTimeout(isScrolling);

        // Set a timeout to run after scrolling ends
        isScrolling = setTimeout(function () {
            //move the table cells. 
            var x = $container.scrollLeft();
            var y = $container.scrollTop();

            $topLeftCell.css('transform', 'translate(' + x + 'px, ' + y + 'px)');
            $headerCells.css('transform', 'translateY(' + y + 'px)');
            $columnCells.css('transform', 'translateX(' + x + 'px)');

            isTopHidden = isLeftHidden = false;
            $topLeftCell.css('visibility', 'inherit');
            $headerCells.css('visibility', 'inherit');
            $columnCells.css('visibility', 'inherit');
        }, 100);

    }, true);

Tabela jest owinięta w div z klasą table-container-fixed.

.table-container-fixed{
    overflow: auto;
    height: 400px;
}

Ustawiam border-collapse na separate, ponieważ w przeciwnym razie tracimy granice podczas tłumaczenia, a ja usuwam obramowanie tabeli, aby zatrzymać zawartość pojawiającą się tuż nad komórką, w której znajdowała się obramowanie podczas przewijania.

.table-container-fixed > table {
   border-collapse: separate;
   border:none;
}

I make th białe tło, aby pokryć komórki pod spodem, a ja dodaję obramowanie pasujące do obramowania tabeli - które jest stylizowane za pomocą Bootstrap i przewijane poza widok.

 .table-container-fixed > table > thead > tr > th {
        border-top: 1px solid #ddd !important;
        background-color: white;        
        z-index: 10;
        position: relative;/*to make z-index work*/
    }

            .table-container-fixed > table > thead > tr > th:first-child {
                z-index: 20;
            }

.table-container-fixed > table > tbody > tr > td:first-child,
.table-container-fixed > table > tfoot > tr > td:first-child {
    background-color: white;        
    z-index: 10;
    position: relative;
}
 0
Author: Colin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 13:38:49

Jakoś skończyłem Position:Sticky działa dobrze na mojej sprawie

table{
  width:100%;
  border:collapse;
  
}
th{
  position: sticky;
    top: 0px;
    border:1px solid black;
    background : #ff5722;
    color:#f5f5f5;
    font-weight:600;
}
td{
    background:#d3d3d3;
    border:1px solid black;
    color:#f5f5f5;
    font-weight:600;
}

div{
  height:150px
  overflow:auto;
  width:100%
}
<div>


<table>
<thead>
<tr>
<th>header 1 </th>
<th>header 2 </th>
<th>header 3 </th>
<th>header 4 </th>
<th>header 5 </th>
<th>header 6 </th>
<th>header 7 </th>
</tr>
</thead>
<tbody>
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>
<tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>
<tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  <tr>
    <td>data 1</td>
    <td>data 2</td>
    <td>data 3</td>
    <td>data 4</td>
    <td>data 5</td>
    <td>data 6</td>
    <td>data 7</td>    
  </tr>  
  
</tbody>
</table>

</div>
 0
Author: Munkhdelger Tumenbayar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-10 09:42:45