Заголовки таблиц HTML всегда отображаются в верхней части окна при просмотре большой таблицы

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

Это было бы концептуально, как "закрепить области" в Excel. Однако HTML-страница может содержать несколько таблиц, и я бы хотел, чтобы это произошло только для текущей таблицы в поле зрения, только пока оно в поле зрения.

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

11 ответов


проверить С помощью jQuery.floatThead (Демос доступен) что очень круто, может работать с DataTables тоже, и может даже работать внутри overflow: auto контейнер.


Я сделал доказательство концепции решения, используя jQuery.

посмотреть образец здесь.

теперь у меня есть этот код Mercurial bitbucket репозиторий. Основной файл tables.html.

Я знаю об одной проблеме с этим: если таблица содержит якоря, и если вы открываете URL с указанным якорем в браузере, когда страница загружается, строка с якорем, вероятно, будет скрытый плавающим заголовком.

обновление 2017-12-11: Я вижу, что это не работает с текущим Firefox (57) и Chrome (63). Не уверен, когда и почему это перестало работать, или как это исправить. Но теперь, я думаю,принят ответ Хенди Irawan выше.


Крейг, я немного доработал ваш код (среди нескольких других вещей, теперь он использует position: fixed) и обернул его как плагин jQuery.

Попробуйте здесь:http://jsfiddle.net/jmosbech/stFcx/

и получить источник здесь:https://github.com/jmosbech/StickyTableHeaders


возможны варианты

JS-floating-table-headers

JS-floating-table-headers (Код Google)

В Drupal

у меня есть сайт на Drupal 6. Я был на странице "модули" администратора и заметил, что таблицы имеют эту точную функцию!

глядя на код, кажется, что он реализован файлом под названием tableheader.js. Он применяет функцию на всех таблицы с классом sticky-enabled.

для сайта Drupal я хотел бы иметь возможность использовать это tableheader.js модуль-это для пользовательского контента. tableheader.js похоже, не присутствует на страницах пользовательского контента в Drupal. Я опубликовал форум чтобы спросить, как изменить тему Drupal, чтобы она была доступна. Согласно ответу,tableheader.js его можно добавить в тему Drupal с помощью drupal_add_js() в тему template.php следующим образом:

drupal_add_js('misc/tableheader.js', 'core');

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

<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>

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

перейти читать на переполнения пристойность, чтобы увидеть, если он соответствует вашим нужно


Это действительно сложная вещь, чтобы иметь липкий заголовок на вашем столе. У меня было такое же требование, но с в ASP:GridView в и затем я обнаружил, что он действительно думал, что имеет липкий заголовок на gridview. Есть много доступных решений, и мне потребовалось 3 дня, чтобы попробовать все решение, но ни одно из них не могло удовлетворить.

основной проблемой, с которой я столкнулся с большинством из этих решений, была проблема выравнивания. Когда вы пытаетесь сделать заголовок плавающим, каким-то образом выравнивание заголовка клетки и клетки тела сбиваются с пути.

С некоторыми решениями я также получил проблему перекрытия заголовка на первые несколько строк тела, что приводит к тому, что строки тела скрываются за плавающим заголовком.

Итак, теперь мне пришлось реализовать свою собственную логику для достижения этого, хотя я также не считаю это идеальным решением, но это также может быть полезно для кого-то,

Ниже приведен пример таблицы.

<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>

Примечание: таблица обернута в DIV с атрибутом класса, равным "table-holder".

Ниже приведен скрипт JQuery, который я добавил в заголовок 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>

и, наконец, ниже приведен класс CSS для бит цели раскраски.

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

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

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

то же решение также работает для asp:gridview, вам нужно добавить еще два шага для достижения этого в gridview,

  1. в событии OnPrerender объекта gridview на вашей веб-странице установите раздел таблицы строки заголовка равным TableHeader.

    if (this.HeaderRow != null)
    {
        this.HeaderRow.TableSection = TableRowSection.TableHeader;
    }
    
  2. и оберните сетку в <div class="table-holder"></div>.

Примечание: если ваш заголовок имеет интерактивные элементы управления, Вам может потребоваться добавить некоторые больше сценария jQuery для передачи событий, вызванных в клонированном заголовке, в исходный заголовок. Этот код уже доступен в плагине jQuery sticky-header create by jmosbech


используя display: fixed на thead раздел должен работать, но для его работы только в текущей таблице вам понадобится помощь JavaScript. И это будет сложно, потому что ему нужно будет выяснить места прокрутки и расположение элементов относительно окна просмотра, что является одной из основных областей несовместимости браузера.

посмотрите на популярные фреймворки JavaScript (jQuery, MooTools, YUI и т. д.) чтобы увидеть, могут ли они делать то, что вы хотите, или сделать это проще делать то, что ты хочешь.


Если вы используете полноэкранную таблицу, вам, возможно, интересно установить th для отображения:fixed; и top:0; или попробуйте очень похожий подход через css.

обновление

просто быстро создайте рабочее решение с помощью iframes (html4.0). Этот пример не соответствует стандарту, однако вы легко сможете его исправить:

внешний.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> 

Если вы ориентируетесь только на современный браузер, следующие два решения даже не нуждаются в js, потому что они просто код css, а также они работают без нарушения макета таблицы. Им также не нужно иметь фиксированную ширину столбца для правильной работы, потому что они просто динамически адаптируются к любому изменению столбца так, как они должны:

следующее Первое решение может быть использовано, если у вас есть только одна строка в элемент thead:

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

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

в то время как вы можете использовать следующее альтернативное решение, если у вас есть две строки head в одной и той же 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 */
}

возможно, Вам придется немного поиграть с top свойство последнего дочернего элемента, изменяющего количество пикселей в соответствии с высотой первой строки (+ поле + граница + заполнение, если таковые имеются), поэтому вторая строка прилипает только вниз ниже первой.

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

по следующему адресу вы можете найти обновленную диаграмму совместимости браузера: https://caniuse.com/#feat=css-sticky


Это доказательство концепции вы сделали было здорово! Однако я также нашел этот плагин jQuery который, кажется, работает очень хорошо. Надеюсь, это поможет!


это расстраивает, что то, что отлично работает в одном браузере, не работает в других. Следующие работы в Firefox, но не в Chrome или 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>