Заголовок таблицы остается фиксированным сверху, когда пользователь прокручивает его вне поля зрения с помощью jQuery

146

Я пытаюсь создать HTML-таблицу, в которой заголовок будет оставаться наверху страницы, когда И ТОЛЬКО, когда пользователь прокручивает его вне поля зрения. Например, таблица может быть на 500 пикселей ниже страницы, как я могу сделать так, чтобы, если пользователь прокручивает заголовок вне поля зрения (браузер как-то обнаруживает, что его больше нет в окне Windows), он останется наверху ? Кто-нибудь может дать мне решение Javascript для этого?

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

Поэтому в приведенном выше примере я хочу <thead>прокрутить страницу, если она выходит из поля зрения.

ВАЖНО: Я НЕ ищу решение, где <tbody>будет полоса прокрутки (переполнение: авто).

Сэм Дюфель
источник
2
дублировать? stackoverflow.com/questions/1030043
Брэд Тофель
Я ответил на другой вопрос, пожалуйста, посмотрите. stackoverflow.com/a/56764334/9388978
Эрсель Актас

Ответы:

131

Вы могли бы сделать что-то подобное, нажав на scrollобработчик событий windowи используя другой tableс фиксированной позицией, чтобы отобразить заголовок вверху страницы.

HTML:

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

CSS:

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

JavaScript:

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

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

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

Это покажет заголовок таблицы, когда пользователь прокрутит вниз достаточно далеко, чтобы скрыть исходный заголовок таблицы. Он снова скроется, когда пользователь снова прокрутит страницу вверх.

Рабочий пример: http://jsfiddle.net/andrewwhitaker/fj8wM/

Эндрю Уитакер
источник
60
Я думал об этом, но что, если ширина столбцов заголовка изменяется в зависимости от содержимого? Если ширина столбцов не фиксирована, строка заголовка может не совпадать со строками содержимого. Просто мысль.
Измир Рамирес
16
этот пример не работает, если имена заголовков столбцов короче значений данных столбцов. Попробуйте изменить эту скрипку таким образом, чтобы она имела значения типа infoooooooo вместо info. Я думаю какая-то жестко заданная ширина, которая устанавливается при клонировании таблицы.
whiterook6
6
Это имеет серьезные ограничения, наименьшее из которых - при попытке использовать таблицу в контейнере, отличном от window. mkoryak.github.io/floatThead предлагает более общее решение.
Юк
13
Это может помочь всем, кому нужна динамическая ширина, это то, что я делал, это форк @AndrewWhitaker: jsfiddle.net/noahkoch/wLcjh/1
Ноа Кох
1
Фиксированный заголовок @NoahKoch, использующий ваше решение, может все еще быть не таким широким, как исходная головка, если в исходных ячейках есть отступы. Я улучшил ваше решение, чтобы добавить отступы для дублированных ячеек. JSFiddle's fork: jsfiddle.net/1n23m69u/2
фэндасон
47

Чистый CSS (без поддержки IE11):

table th {
    position: -webkit-sticky; // this is for all Safari (Desktop & iOS), not for Chrome
    position: sticky;
    top: 0;
    z-index: 5;
    background: #fff;
}
Игорь Зенич
источник
1
Я даже не вижу, как это работает в Chrome. Инструменты проверки отображаются -webkit-stickyкак недопустимое значение для position.
карменизм
@carmenism -webkit-stickyдля Safari (для настольных ПК и iOS), а не для Chrome. position: stickyработает в Chrome с версии 56. Вы должны установить ОБА правила: -webkit-stickyи stickyточно в том же порядке, что и в моем примере кода. Safari получает webkit-stickyи все другие браузеры перезаписывают его sticky.
Игорь Зенич
2
Я не смог заставить это работать. Похоже, из быстрого Google не position: stickyбудет работать с элементами таблицы.
rjh
3
Подача
1
Вы должны применить это к th, потому что это не будет работать ни на
thead,
46

Ну, я пытался получить тот же эффект, не прибегая к столбцам фиксированного размера или имея фиксированную высоту для всей таблицы.

Решение, которое я придумал, - взломать. Он состоит из дублирования всей таблицы, затем скрытия всего, кроме заголовка, и создания фиксированной позиции.

HTML

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

CSS

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

Javascript

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

Посмотреть здесь: http://jsfiddle.net/QHQGF/7/

Редактировать: обновил код, чтобы thead мог получать события указателя (чтобы кнопки и ссылки в заголовке все еще работали). Это решает проблему, о которой сообщили Лухфлух и Джо М.

Новый jsfiddle здесь: http://jsfiddle.net/cjKEx/

энтропия
источник
3
Сначала я попробовал, проблема в том, что размер элементов в заголовке зависит от содержимого таблицы. Если у вас есть строка с большим содержанием, весь столбец, включая заголовок, будет расти. Если вы клонируете только thead, вы теряете эту информацию и не получаете желаемого эффекта. См. Комментарий Измира Рамиреса к принятому ответу. Это единственный способ, который я нашел, который работает без столбцов фиксированной ширины. Я знаю, что это не чисто, и я сказал, что это взлом.
энтропия
1
О, я понял. Этот метод хорош, потому что он работает с жидкостными колонками, я немного погуглил и не смог найти другой с такой функциональностью. В любом случае, если я сделаю это как-нибудь, я упомяну это здесь
M2_
1
@luhfluh, да, проблема была из-за событий указателя: ни одного в клонированной таблице. Это используется для того, чтобы клики проходили через клон и к исходной таблице. Возврат его в заголовок клонированной таблицы, чтобы заголовок (и только заголовок) можно было щелкнуть, устраняет проблему. Я обновил свой пост, чтобы отразить это :)
энтропия
4
проблема с добавлением границы <thead> <th>
Jam Ville
1
@JamVille Потому что клонированная таблица имеет visibility: hidden. Вы можете скрыть только #clone tbodyи после этого вы можете установить границу ... Рабочая скрипка: jsfiddle.net/QHQGF/1707
Лайдак Марек
26

Я написал плагин, который делает это. Я работаю над этим уже около года, и думаю, что он хорошо справляется со всеми угловыми делами:

  • прокрутка внутри контейнера с переполнением
  • прокрутка в окне
  • заботиться о том, что происходит при изменении размера окна
  • сохраняя ваши события привязанными к заголовку
  • самое главное это не заставляет вас менять CSS вашего стола, чтобы он работал

Вот несколько демонстраций / документов:
http://mkoryak.github.io/floatThead/

mkoryak
источник
большое усилие, но не работает с IE 10 и имеет некоторые особенности при изменении размеров окон в firefox23 / ubuntu.
января
2
К вашему сведению: я исправил проблемы с IE9 и 10 в последней версии.
mkoryak
2
Можете ли вы сделать версию, которая не требует jQuery?
Кертис W
2
вероятно, потому что он не использует jquery ... и нет - я не буду делать версию, которая не использует jquery.
Мкоряк
1
Я использую простой плагин jQery tablesorter и, согласно вашему FAQ, вашему плагину не нравятся большинство правил CSS, таких как #sortable td {..} и так далее. Я попытался немного подправить, но не смог заставить его работать.
masche
25

Мне удалось исправить проблему с изменением ширины столбца. Я начал с решения Эндрю выше (большое спасибо!), А затем добавил один маленький цикл, чтобы установить ширину клонированных ТД:

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

Это решает проблему без клонирования всей таблицы и скрытия тела. Я новичок в JavaScript и jQuery (и для переполнения стека), поэтому любые комментарии приветствуются.

rockusbacchus
источник
4
Работало хорошо, но мне нужно было добавить следующую строку $ ("# header-fixed"). Width ($ ("# table-1"). Width ()); чтобы столбцы выстроились правильно.
Илья Федотов
17

На сегодняшний день это лучшее решение, которое я нашел для фиксированного заголовка таблицы.

ОБНОВЛЕНИЕ 5/11: Исправлена ​​ошибка горизонтальной прокрутки, как указано Керри Джонсон

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

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

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

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

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

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

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

.blue thead{
  background:#1ABC9C;
}

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

.purple thead{
  background:#9B59B6;
}

thead{
  color:white;
}

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

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

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

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

.scrollMore{
  margin-top:600px;
}

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

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

josephting
источник
Я исправил этот скрипт, чтобы он мог обрабатывать элементы <th>, имеющие границы и отступы (в противном случае он устанавливает ширину фиксированного заголовка <th> слишком широкой). Просто измените outerWidthна widthв определении функции resizeFixed ().
alanng
Вам также может понадобиться добавить свойство CSS z-indexк некоторому положительному числу в .fixedклассе, чтобы объекты, отображаемые после загрузки страницы в таблице, не плавали поверх фиксированного заголовка при прокрутке.
alanng
Просто и полезно.
RitchieD
как динамически обрабатывать верхнюю позицию. Допустим, мне нужно прокрутить вверх под содержание главной страницы с фиксированным заголовком. .fixed {top: 0;} .
Виджай Вишну
2
@KerryJohnson Спасибо за примечание. Я сделал некоторые изменения, чтобы он поддерживал горизонтальную прокрутку и динамическую ширину столбцов.
Джозефтинг
7

Лучшее решение - использовать этот плагин jquery:

https://github.com/jmosbech/StickyTableHeaders

Этот плагин отлично сработал для нас, и мы попробовали много других решений. Мы проверили это в IE, Chrome и Firefox

Janning
источник
Знаете ли вы какое-либо решение, которое также сохраняет функциональность элементов управления привязкой данных в заголовке?
Чаба Тот
У меня не сработало: заголовки находятся за пределами таблицы и прикрепляются к верхней части браузера (окна), даже с опцией "scrollableArea". Я видел, что это было упомянуто ранее без дополнительных комментариев. Возможно, ему нужен CSS, который он использует, и он недоступен, чтобы заставить его работать.
Exel Gamboa
6

Здесь уже есть много действительно хороших решений. Но одно из самых простых CSS-решений, которые я использую в этих ситуациях, заключается в следующем:

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

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

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

Поскольку нет необходимости в JavaScript, это значительно упрощает ситуацию. Вы должны сосредоточиться на втором правиле CSS, которое содержит условия для обеспечения того, чтобы заголовок таблицы оставался сверху независимо от места прокрутки.

Детально проработать каждое из правил. positionпредназначено для указания браузеру, что объект head, его строка и его ячейки должны придерживаться вершины. Это обязательно должно сопровождаться top, что указывает браузеру, что голова будет придерживаться верхней части страницы или области просмотра. Кроме того, вы можете добавитьz-index чтобы содержимое заголовка всегда оставалось сверху.

Цвет фона просто для иллюстрации сути. Вам не нужно использовать какой-либо дополнительный JavaScript, чтобы получить этот эффект. Это поддерживается в большинстве основных браузеров после 2016 года.

Шриватс Шанкар
источник
1
Самый простой и понятный ответ, всегда есть простой способ решить одну проблему, это так. Хотя я использую ng-repeat с angularjs, он работает как шарм.
Дэвид Кастро
5

Я нашел простую библиотеку jQuery под названием Sticky Table Headers. Две строки кода, и он сделал именно то, что я хотел. Приведенные выше решения не управляют шириной столбцов, поэтому, если у вас есть ячейки таблицы, которые занимают много места, результирующий размер постоянного заголовка не будет соответствовать ширине вашей таблицы.

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

Информация об использовании здесь: https://github.com/jmosbech/StickyTableHeaders

Лок Ян Вонг
источник
3

Ну, после обзора всех доступных решений я написал плагин, который может заморозить любую строку (не только th) вверху страницы или контейнера. Это очень просто и очень быстро. Не стесняйтесь использовать его. http://maslianok.github.io/stickyRows/

Виталий Маслянок
источник
3

Вы можете использовать этот подход, чистый HTML и CSS не нужны JS :)

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

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

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

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

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

xelilof
источник
3

Я нашел простое решение без использования JQuery и CSS только .

Вы должны поместить фиксированное содержимое в теги th и добавить CSS

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

Позиции, z-index и top достаточно. Но вы можете применить остальное, чтобы дать для лучшего обзора.

Абхи Дас
источник
2

Я тоже испытывал те же проблемы с тем, что форматирование границ не показывалось с помощью кода entrophy, но было несколько небольших исправлений, и теперь таблица расширяется и отображает все правила стилей CSS, которые вы можете добавить.

к css добавить:

#maintable{width: 100%}    

тогда вот новый javascript:

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

            $("#table-container").append(clone_table);
            // dont hide the whole table or you lose border style & 
            // actively match the inline width to the #maintable width if the 
            // container holding the table (window, iframe, div) changes width          
            $("#clone").width($("#maintable").width());
            // only the clone thead remains visible
            $("#clone thead").css({
                visibility:"visible"
            });
            // clone tbody is hidden
            $("#clone tbody").css({
                visibility:"hidden"
            });
            // add support for a tfoot element
            // and hide its cloned version too
            var footEl = $("#clone tfoot");
            if(footEl.length){
                footEl.css({
                    visibility:"hidden"
                });
            }
        }
    } 
    else {
        $("#clone").remove();
    }
}
$(window).scroll(moveScroll);
seeit360
источник
Это работает лучше, чем решение энтропии, поскольку форматирование границ идет в заголовке. Однако в текущем Firefox (но не в Chrome) он создает видимые артефакты границы ячейки под таблицей после начала прокрутки.
alanng
2

Вот решение, основанное на принятом ответе. Он корректирует: ширину столбцов, соответствующий стиль таблицы и время прокрутки таблицы в контейнере div.

использование

Убедитесь, что в вашей таблице есть <thead>тег, потому что будет исправлено только содержание.

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

Javasript

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

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

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

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

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

                }
                else if (offset <= tableOffset && !$tableFixed.is(":hidden")) {
                    $tableFixed.hide();
                }
            });
        });
    };
})(jQuery);
Бен Грипка
источник
1
Это хорошо сработало для меня. Единственная вещь - это проблема с таблицами, которые нужно прокручивать горизонтально. Я сделал обновление в JSFiddle здесь jsfiddle.net/4mgneob1/1 Я вычитаю,$sp.scrollLeft() который получает сумму, прокручиваемую слева, поэтому при прокрутке вниз фиксированная таблица расположена правильно. Также добавлена ​​проверка при горизонтальной прокрутке, если виден фиксированный стол, чтобы отрегулировать левое положение. Еще одна проблема, которую я не мог решить, - когда таблица выходит за область просмотра, она должна скрываться до тех пор, пока пользователь не выполнит прокрутку назад.
Хенеснарфель
1
НачалоUncaught TypeError: $table.scrollParent is not a function
Карлинген
1

Это поможет вам иметь фиксированный заголовок, который также можно прокручивать по горизонтали с данными.

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



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

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

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

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

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

    <div id="full">




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

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

            </table>
        </div>




        <div id="innertablediv">

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

            </table>
        </div>
    </div>
</body>
</html>
user2669926
источник
Это поможет вам иметь фиксированный заголовок, который также можно прокручивать по горизонтали с данными.
user2669926
1
function fix_table_header_position(){
 var width_list = [];
 $("th").each(function(){
    width_list.push($(this).width());
 });
 $("tr:first").css("position", "absolute");
 $("tr:first").css("z-index", "1000");
 $("th, td").each(function(index){
    $(this).width(width_list[index]);
 });

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

Это мое решение

Просто мы
источник
1

Немного опоздал на вечеринку, но здесь есть реализация, которая работает с несколькими таблицами на одной и той же странице и бесплатно (с использованием requestAnimationFrame). Также нет необходимости указывать ширину столбцов. Горизонтальная прокрутка работает также.

Заголовки определены в, divтак что вы можете добавить любую разметку (например, кнопки), если это необходимо. Это все, что нужно HTML:

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

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

Лео
источник
1

В этом решении фиксированный заголовок создается динамически, контент и стиль клонируются из THEAD.

все, что вам нужно, это две строки, например:

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

Мой плагин jquery FixedHeader и getStyleObject, представленные ниже, вы можете поместить в файл .js.

// JAVASCRIPT



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

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



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





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

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

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

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


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

Петр С.
источник
1

Создайте дополнительную таблицу с тем же заголовком, что и основная таблица. Просто поместите thead в новую таблицу с одним рядом и всеми заголовками в ней. Делайте положение абсолютного и белого фона. Для основной таблицы поместите его в div и используйте некоторую прокрутку по высоте и переполнению. Таким образом, наша новая таблица преодолеет заголовок главной таблицы и останется там. Окружите все в div. Ниже приведен приблизительный код для этого.

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

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


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

                                    </table>
              </div>
        </div>
Novice_JS
источник
1

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

Демо: демоверсия фиксированного заголовка таблицы css

revilodesign.de
источник
1

Исправьте эту проблему с этим

tbody {
  display: table-caption;
  height: 200px;
  caption-side: bottom;
  overflow: auto;
}
J Benjamín Samayoa
источник
0

Это может быть достигнуто с помощью преобразования свойства стиля. Все, что вам нужно сделать, это обернуть вашу таблицу в некоторый div с фиксированной высотой и переполнением, установленным на auto, например:

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

И затем вы можете присоединить к нему обработчик onscroll, здесь у вас есть метод, который находит каждую таблицу, завернутую в <div class="tableWrapper"></div>:

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

И вот рабочий пример этого в действии (я использовал bootstrap, чтобы сделать его красивее): fiddle

Для тех, кто также хочет поддерживать IE и Edge, вот фрагмент:

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

В IE и Edge прокрутка немного запаздывает ... но работает

Вот ответ, который помогает мне узнать это: ответ

Даниэль Будзыньски
источник
0

Я испробовал большинство из этих решений и в итоге нашел (IMO) лучшее современное решение:

CSS сетки


С помощью CSS-сеток вы можете определить «сетку» и, наконец, создать красивое кросс-браузерное решение без использования JavaScript для таблицы с фиксированным заголовком и прокручиваемого содержимого. Высота заголовка может быть даже динамической.

CSS : отобразить в виде сетки и установить количество template-rows:

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

HTML : создайте контейнер сетки и определите количество rows:

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

Вот рабочий пример:

CSS

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

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

HTML

<html>
    <head>
    </head>
    <body>
        <div class="table">
            <div class="table-heading">
                HEADING
            </div>
            <div class="table-content">
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
            </div>
        </div>
    </body>
</html>
Джеффри Розендал
источник
0

Я пробовал это с помощью преобразования: перевод . Хотя он хорошо работает в Firefox и Chrome, в IE11 просто нет функции. Нет двойных полос прокрутки. Поддерживает таблицу tfoot и заголовок. Чистый Javascript, нет JQuery.

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

thead.style.transform="translate(0,"+(dY-top-1)+"px)";
Хенрик Хафтманн
источник
0

Я нашел решение без jquery

HTML

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

CSS

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

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

.fixed_header thead tr {
   display: block;
}

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

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

Вы можете увидеть это работает здесь: https://jsfiddle.net/lexsoul/fqbsty3h

Источник: https://medium.com/@vembarrajan/html-css-tricks-scroll-able-table-body-tbody-d23182ae0fbc

Lexsoul
источник