Ответ 1
Отъезд jQuery.floatThead (доступные демо), что очень круто, может работать с DataTables и может даже работать внутри контейнера overflow: auto
.
Я хотел бы иметь возможность "настроить" представление таблицы HTML, чтобы добавить одну функцию: при прокрутке страницы, чтобы таблица была на экране, но строки заголовков вне экрана, я хотел бы, чтобы чтобы они были видны в верхней части области просмотра.
Это было бы концептуально похоже на функцию "замораживания окон" в Excel. Тем не менее, HTML-страница может содержать несколько таблиц, и я бы хотел, чтобы это произошло для таблицы, которая в настоящее время находится в режиме просмотра, только пока она находится в режиме просмотра.
Примечание. Я видел одно решение, в котором область данных таблицы выполнена прокручиваемой, в то время как заголовки не прокручиваются. Это не решение, которое я ищу.
Отъезд jQuery.floatThead (доступные демо), что очень круто, может работать с DataTables и может даже работать внутри контейнера overflow: auto
.
Я разработал концептуальное решение, используя jQuery.
Теперь я получил этот код в репозитории Mercurial bitbucket. Основной файл tables.html
.
Мне известно об одной проблеме: если таблица содержит привязки, и если вы откроете URL-адрес с указанным якорем в браузере, когда страница загружается, строка с якорем, вероятно, будет скрыта плавающей заголовок.
Обновление 2017-12-11: Я вижу, что это не работает с текущими Firefox (57) и Chrome (63). Не уверен, когда и почему это перестало работать, или как это исправить. Но теперь, я думаю, принятый ответ Хенди Иравана превосходит.
Крейг, я немного уточнил ваш код (среди нескольких других вещей, которые он теперь использовал положением: исправлено) и завернул его как плагин jQuery.
Попробуйте здесь: http://jsfiddle.net/jmosbech/stFcx/
И получите источник здесь: https://github.com/jmosbech/StickyTableHeaders
Если вы ориентируетесь на современные css3-совместимые браузеры (поддержка браузеров : https://caniuse.com/#feat=css-sticky), вы можете использовать position:sticky
, которая не требует JS и не нарушит компоновку таблицы. выравнивание th и td одного столбца. Также не требуется фиксированная ширина столбца для правильной работы.
Пример для отдельной строки заголовка:
thead th
{
position: sticky;
top: 0px;
}
Для theads с 1 или 2 рядами вы можете использовать что-то вроде этого:
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, и просто исчезает, когда вся таблица прокручивается вниз. Так что если есть больше таблиц, все прекрасно работают одинаково.
Зачем использовать last-child до и first-child после в css?
Поскольку правила CSS отображаются браузером в том же порядке, в каком вы их записываете в файл CSS, и из-за этого, если у вас есть только 1 строка в элементе thead, первая строка одновременно является последней строкой, а правило first-child необходимо переопределить последний ребенок. Если нет, у вас будет смещение строки в 30 пикселей от верхнего поля, которое, я полагаю, вам не нужно.
Известная проблема position: sticky состоит в том, что она не работает с элементами thead или строками таблицы: вы должны использовать th-элементы. Эта проблема будет решена в будущих версиях браузера.
Возможные альтернативы
JS-плавающие-таблицы заголовки
js-float-table-headers (Google Code)
В Друпале
У меня есть сайт Drupal 6. Я был на странице администратора "Модули", и заметил, что таблицы имеют именно эту функцию!
Глядя на код, кажется, что он реализован в файле с именем tableheader.js
. Он применяет эту функцию ко всем таблицам с sticky-enabled
классом sticky-enabled
.
Для сайта на Drupal я хотел бы иметь возможность использовать этот модуль tableheader.js
как есть для пользовательского контента. 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 с атрибутом класса, равным "держателю таблицы".
Ниже приведен JQuery script, который я добавил в свой заголовок страницы 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 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;
}
Таким образом, вся идея этой логики заключается в том, чтобы поместить таблицу в разделитель таблицы и создать клон этого держателя на стороне клиента при загрузке страницы. Теперь скройте тело таблицы внутри держателя клонов и поместите оставшуюся часть заголовка в исходный заголовок.
То же решение также работает для asp: gridview, вам нужно добавить еще два шага для достижения этого в gridview,
В событии OnPrerender объекта gridview на вашей веб-странице установите столбец таблицы заголовков, равный TableHeader.
if (this.HeaderRow != null)
{
this.HeaderRow.TableSection = TableRowSection.TableHeader;
}
И заверните свою сетку в <div class="table-holder"></div>
.
Примечание. Если в заголовке есть элементы управления, доступные клиенту, вам может потребоваться добавить еще несколько jQuery script, чтобы передать события, поднятые в клонированном заголовке, в исходный заголовок. Этот код уже доступен в плагине jQuery sticky-header, созданный jmosbech
Если вы используете полноэкранную таблицу, вам может быть интересно установить th для отображения: fixed; и верх: 0; или попробуйте очень похожий подход через css.
Обновление
Просто быстро создайте рабочее решение с iframes (html4.0). Этот пример НЕ соответствует стандарту, однако вы легко сможете его исправить:
outer.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>
Использование display: fixed
в разделе thead
должно работать, но для этого он работает только в текущей таблице, вам понадобится помощь JavaScript. И это будет сложно, потому что ему нужно будет определить прокручиваемые места и местоположение элементов относительно окна просмотра, что является одной из главных областей несовместимости браузера.
Взгляните на популярные JavaScript-фреймворки (jQuery, MooTools, YUI и т.д.), чтобы узнать, могут ли они делать то, что вы хотите, или облегчить выполнение того, что вы хотите.
Что доказательство концепции, которое вы сделали, было здорово! Однако я также нашел этот плагин 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>
Спасибо! (У меня такой же вопрос) :-)