Nagłówki tabeli HTML zawsze widoczne u góry okna podczas wyświetlania dużej tabeli

Chciałbym móc "dostosować" prezentację tabeli HTML, aby dodać jedną funkcję: podczas przewijania w dół strony, aby tabela była na ekranie, ale wiersze nagłówków są poza ekranem, chciałbym, aby nagłówki pozostały widoczne u góry obszaru wyświetlania.

Byłoby to koncepcyjnie podobne do funkcji "zamrożenie paneli" w programie Excel. Jednak strona HTML może zawierać kilka tabel i chciałbym, aby stało się to tylko dla tabeli, która jest obecnie w widoku, tylko póki jest na widoku.

Uwaga: widziałem jedno rozwiązanie, w którym obszar danych tabeli jest przewijany, podczas gdy nagłówki nie przewijają się. Nie takiego rozwiązania Szukam.

Author: Christopher Rapcewicz, 2009-06-23

11 answers

Zobacz jQuery.floatThead (dostępne dema), który jest bardzo fajny, może pracować z DataTables , a nawet może pracować wewnątrz overflow: auto kontenera.

 62
Author: Hendy Irawan,
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-02 16:27:04

Zrobiłem rozwiązanie proof-of-concept używając jQuery .

Zobacz próbkę tutaj.

Mam teraz ten kod w Mercurial bitbucket repozytorium . Głównym plikiem jest tables.html.

Zdaję sobie sprawę z jednego problemu: jeśli tabela zawiera kotwice i jeśli otworzysz adres URL za pomocą podanej kotwicy w przeglądarce, gdy Strona się ładuje, wiersz z kotwicą prawdopodobnie zostanie zasłonięty przez pływający nagłówek.

Aktualizacja 2017-12-11: widzę, że to nie działa z obecnym Firefoksem (57) i Chrome (63). Nie wiem, kiedy i dlaczego to przestało działać, ani Jak to naprawić. Ale teraz myślę, że zaakceptowana odpowiedź Hendy ' ego Irawana jest lepsza.

 133
Author: Craig McQueen,
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-12-11 05:37:16

Craig, trochę dopracowałem Twój kod (między innymi używa position: fixed) i owinąłem go jako wtyczkę jQuery.

Spróbuj tutaj: http://jsfiddle.net/jmosbech/stFcx/

I pobierz źródło tutaj: https://github.com/jmosbech/StickyTableHeaders

 66
Author: jmosbech,
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
2011-10-10 20:23:10

Możliwe alternatywy

Js-floating-table-headers

Js-floating-table-headers (Google Code)

W Drupal

Mam stronę Drupal 6. Byłem na stronie Admin "moduły" i zauważyłem, że tabele mają dokładnie tę funkcję!

Patrząc na kod, wydaje się, że jest on zaimplementowany przez plik o nazwie tableheader.js. Stosuje tę funkcję we wszystkich tabelach z klasą sticky-enabled.

Dla strony Drupal, chciałbym aby móc z tego skorzystać tableheader.js Moduł as-is dla treści użytkownika. tableheader.js nie wydaje się być obecny na stronach Treści Użytkownika w Drupal. Opublikowałem wiadomość forum , aby zapytać, jak zmodyfikować motyw Drupala, aby był dostępny. Zgodnie z odpowiedzią, tableheader.js może być dodany do motywu Drupala za pomocą drupal_add_js() w temacie template.php w następujący sposób:

drupal_add_js('misc/tableheader.js', 'core');
 5
Author: Craig McQueen,
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-07-19 15:53:46

Spotkałem się z tym problemem bardzo niedawno. Niestety, musiałem zrobić 2 tabele, jeden dla nagłówka i jeden dla ciała. To chyba nie jest najlepsze podejście, ale tutaj idzie:

<html>
<head>
    <title>oh hai</title>
</head>
<body>
    <table id="tableHeader">
        <tr>
            <th style="width:100px; background-color:#CCCCCC">col header</th>
            <th style="width:100px; background-color:#CCCCCC">col header</th>
        </tr>
    </table>
    <div style="height:50px; overflow:auto; width:250px">
        <table>
            <tr>
                <td style="height:50px; width:100px; background-color:#DDDDDD">data1</td>
                <td style="height:50px; width:100px; background-color:#DDDDDD">data1</td>
            </tr>
            <tr>
                <td style="height:50px; width:100px; background-color:#DDDDDD">data2</td>
                <td style="height:50px; width:100px; background-color:#DDDDDD">data2</td>
            </tr>
        </table>
    </div>
</body>
</html>

To działało dla mnie, to prawdopodobnie nie jest elegancki sposób, ale to działa. Zbadam więc zobaczyć, czy mogę zrobić coś lepszego, ale pozwala na wiele tabel.

Idź poczytaj na przepełnienie aby sprawdzić, czy pasuje do Twoich potrzeb

 4
Author: Gab Royer,
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-09-23 14:15:18

To naprawdę trudna rzecz mieć lepki nagłówek na stole. Miałem ten sam wymóg, ale z asp: GridView i okazało się, że naprawdę myślałem, że ma sticky header na gridview. Dostępnych jest wiele rozwiązań i zajęło mi to 3 dni, próbując wszystkich rozwiązań, ale żaden z nich nie mógł zaspokoić.

Głównym problemem, z którym borykałem się z większością tych rozwiązań, był problem wyrównania. Podczas próby unoszenia nagłówka, w jakiś sposób wyrównanie komórek nagłówka i ciała / align = "left" /

Z niektórymi rozwiązaniami, mam również problem z nałożeniem nagłówka na kilka pierwszych rzędów ciała, co powoduje, że wiersze ciała są ukryte za pływającym nagłówkiem.

Więc teraz musiałem wdrożyć własną logikę, aby to osiągnąć, choć również nie uważam tego za idealne rozwiązanie, ale może to być również pomocne dla kogoś,

Poniżej znajduje się przykładowa tabela.

<div class="table-holder">
        <table id="MyTable" cellpadding="4" cellspacing="0" border="1px" class="customerTable">
            <thead>
                <tr><th>ID</th><th>First Name</th><th>Last Name</th><th>DOB</th><th>Place</th></tr>
            </thead>
            <tbody>
                <tr><td>1</td><td>Customer1</td><td>LastName</td><td>1-1-1</td><td>SUN</td></tr>
                <tr><td>2</td><td>Customer2</td><td>LastName</td><td>2-2-2</td><td>Earth</td></tr>
                <tr><td>3</td><td>Customer3</td><td>LastName</td><td>3-3-3</td><td>Mars</td></tr>
                <tr><td>4</td><td>Customer4</td><td>LastName</td><td>4-4-4</td><td>Venus</td></tr>
                <tr><td>5</td><td>Customer5</td><td>LastName</td><td>5-5-5</td><td>Saturn</td></tr>
                <tr><td>6</td><td>Customer6</td><td>LastName</td><td>6-6-6</td><td>Jupitor</td></tr>
                <tr><td>7</td><td>Customer7</td><td>LastName</td><td>7-7-7</td><td>Mercury</td></tr>
                <tr><td>8</td><td>Customer8</td><td>LastName</td><td>8-8-8</td><td>Moon</td></tr>
                <tr><td>9</td><td>Customer9</td><td>LastName</td><td>9-9-9</td><td>Uranus</td></tr>
                <tr><td>10</td><td>Customer10</td><td>LastName</td><td>10-10-10</td><td>Neptune</td></tr>
            </tbody>
        </table>
    </div>

Notatka : tabela jest owinięta w DIV z atrybutem klasy równym "uchwyt stołowy".

Poniżej znajduje się skrypt JQuery, który dodałem w nagłówku strony html.

<script src="../Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="../Scripts/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function () {
        //create var for table holder
        var originalTableHolder = $(".table-holder");
        // set the table holder's with
        originalTableHolder.width($('table', originalTableHolder).width() + 17);
        // Create a clone of table holder DIV
        var clonedtableHolder = originalTableHolder.clone();

        // Calculate height of all header rows.
        var headerHeight = 0;
        $('thead', originalTableHolder).each(function (index, element) {
            headerHeight = headerHeight + $(element).height();
        });

        // Set the position of cloned table so that cloned table overlapped the original
        clonedtableHolder.css('position', 'relative');
        clonedtableHolder.css('top', headerHeight + 'px');

        // Set the height of cloned header equal to header height only so that body is not visible of cloned header
        clonedtableHolder.height(headerHeight);
        clonedtableHolder.css('overflow', 'hidden');

        // reset the ID attribute of each element in cloned table
        $('*', clonedtableHolder).each(function (index, element) {
            if ($(element).attr('id')) {
                $(element).attr('id', $(element).attr('id') + '_Cloned');
            }
        });

        originalTableHolder.css('border-bottom', '1px solid #aaa');

        // Place the cloned table holder before original one
        originalTableHolder.before(clonedtableHolder);
    });
</script>

I w końcu poniżej jest klasa CSS do celów kolorowania.

.table-holder
{
    height:200px;
    overflow:auto;
    border-width:0px;    
}

.customerTable thead
{
    background: #4b6c9e;        
    color:White;
}

Więc cała idea tej logiki polega na umieszczeniu tabeli w tabeli holder div I utworzeniu klonu tego hold ' a po stronie klienta po załadowaniu strony. Teraz Ukryj ciało tabeli wewnątrz uchwytu klonowania i umieść pozostałą część nagłówka nad oryginalnym nagłówkiem.

To samo rozwiązanie działa również dla asp: GridView, musisz dodać jeszcze dwa kroki, aby to osiągnąć w gridview,

  1. W zdarzeniu OnPrerender obiektu gridview na twojej stronie internetowej Ustaw sekcję tabeli w wierszu nagłówka równą Nagłówkowi tabeli.

    if (this.HeaderRow != null)
    {
        this.HeaderRow.TableSection = TableRowSection.TableHeader;
    }
    
  2. I zawiń swoją siatkę w <div class="table-holder"></div>.

Uwaga: Jeśli twój nagłówek ma klikalne kontrolki, może być konieczne dodanie kilku skryptów jQuery, aby przekazać zdarzenia podniesione w sklonowanym nagłówku do oryginalnego nagłówka. Kod ten jest już dostępny w jQuery sticky-header plugin create by jmosbech

 3
Author: Prasoon,
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-02-20 22:07:38

Korzystanie z display: fixed w sekcji thead powinno działać, ale aby działało tylko na bieżącej tabeli w widoku, potrzebujesz pomocy JavaScript. I to będzie trudne, ponieważ będzie musiał dowiedzieć się przewijania miejsc i lokalizacji elementów w stosunku do viewport, który jest jednym z głównych obszarów niekompatybilności przeglądarki.

Przyjrzyj się popularnym frameworkom JavaScript (jQuery, MooTools, YUI, etc itd.), aby sprawdzić, czy mogą albo zrobić to, co chcesz, albo ułatwić chcę.

 2
Author: staticsan,
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
2009-06-23 00:42:56

Jeśli używasz tabeli pełnoekranowej, być może jesteś zainteresowany ustawieniem TH NA display: fixed; and top:0; lub spróbuj bardzo podobnego podejścia za pomocą css.

Update

Wystarczy szybko zbudować działające rozwiązanie z iframes (html4.0). Ten przykład nie jest standardowym conform, jednak można go łatwo naprawić:

Zewnętrzne.html

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">   
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">     
    <head>      
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />   
        <title>Outer</title>
  <body>
    <iframe src="test.html" width="200" height="100"></iframe>
    </body>
</html> 

Test.html

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">   
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">     
    <head>      
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />   
        <title>Floating</title>
    <style type="text/css">
      .content{
        position:relative; 
      }

      thead{
        background-color:red;
        position:fixed; 
        top:0;
      }
    </style>
  <body>
    <div class="content">      
      <table>
        <thead>
          <tr class="top"><td>Title</td></tr>
        </head>
        <tbody>
          <tr><td>a</td></tr>
          <tr><td>b</td></tr>
          <tr><td>c</td></tr>
          <tr><td>d</td></tr>
          <tr><td>e</td></tr>
          <tr><td>e</td></tr>
          <tr><td>e</td></tr>
          <tr><td>e</td></tr>
          <tr><td>e</td></tr>
          <tr><td>e</td></tr>
        </tbody>
      </table>
    </div>
    </body>
</html> 
 2
Author: merkuro,
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
2009-06-23 00:54:44

Jeśli kierujesz się tylko do nowoczesnej przeglądarki, następujące dwa rozwiązania nie potrzebują nawet js, ponieważ są tylko kodem css, a także działają bez łamania układu tabeli. Nie muszą również mieć stałej szerokości kolumny, aby działać poprawnie, ponieważ dostosowują się dynamicznie do każdej kolumny, zmieniając sposób, w jaki muszą:

Następujące pierwsze rozwiązanie może być użyte, jeśli masz tylko jeden wiersz w elemencie thead:

thead th
{
    position: sticky;
    top: 0px;
}

Poprzedni kod działa, jeśli każda tabela, którą chcesz mieć zakleszczoną głowę ma tylko jeden rząd głowy.

Podczas gdy możesz użyć następującego alternatywnego rozwiązania, jeśli masz dwa rzędy głowy w tym samym thead:

thead > :last-child th
{
    position: sticky;
    top: 30px; /* This is for all the the "th" elements in the second row, (in this casa is the last child element into the thead) */
}

thead > :first-child th
{
    position: sticky;
    top: 0px; /* This is for all the the "th" elements in the first child row */
}

Być może będziesz musiał trochę pobawić się właściwością top ostatniego dziecka zmieniającą liczbę pikseli, aby pasowała do wysokości pierwszego rzędu (+margines + obramowanie + padding, jeśli istnieje), więc drugi wiersz przykleja się poniżej pierwszego.

Również oba rozwiązania działają, nawet jeśli masz więcej niż jedną tabelę na tej samej stronie: element TH każdego z nich zaczyna być lepki, gdy jego górna pozycja jest wskazana w definicji css i po prostu znikają, gdy cała tabela przewija się w dół. Więc jeśli jest więcej tabel, wszystkie działają pięknie w ten sam sposób.

Pod poniższym adresem można znaleźć zaktualizowaną tabelę zgodności przeglądarki: https://caniuse.com/#feat=css-sticky

 2
Author: willy wonka,
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-05-22 20:17:20

Ten dowód koncepcji był świetny! Jednak znalazłem również Ten jQuery plugin , który wydaje się działać bardzo dobrze. Mam nadzieję, że to pomoże!

 0
Author: Marco,
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
2011-07-28 22:06:14

To frustrujące, że to, co działa świetnie w jednej przeglądarce, nie działa w innych. W Firefoksie, ale nie w Chrome czy IE:

<table width="80%">

 <thead>

 <tr>
  <th>Column 1</th>
  <th>Column 2</th>
  <th>Column 3</th>
 </tr>

 </thead>

 <tbody style="height:50px; overflow:auto">

  <tr>
    <td>Cell A1</td>
    <td>Cell B1</td>
    <td>Cell C1</td>
  </tr>

  <tr>
    <td>Cell A2</td>
    <td>Cell B2</td>
    <td>Cell C2</td>
  </tr>

  <tr>
    <td>Cell A3</td>
    <td>Cell B3</td>
    <td>Cell C3</td>
  </tr>

 </tbody>

</table>
 0
Author: Peter Dow,
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
2011-12-14 21:01:15