Заголовок замороженной таблицы внутри прокручиваемого div
У меня три дива. Верхний и нижний колонтитулы. В центральном div (gridview) есть таблица, которая почти всегда длиннее внешнего div. Так что я сделал этот div прокручиваемый по вертикали. Вопрос в том, как сделать заголовок таблицы, который будет виден после прокрутки div? Я мог бы сделать этот заголовок с отдельным div или таблицей и сделать его фиксированным, но ширина столбцов в таблице не всегда одинакова - поэтому я не знаю, как поддерживать ширину столбцов в заголовке. Любая подсказка?
11 ответов
Вот базовое решение с использованием JavaScript:
function position(table) {
table.rows[0].style.position="absolute";
table.rows[0].style.top="0px";
table.style.marginTop = table.rows[0].clientHeight/1.2;
var widths = Array();
for(var i = 0; i < table.rows[0].cells.length; i++) {
widths[i] = max(table.rows[0].cells[i].clientWidth, table.rows[1].cells[i].clientWidth);
}
for(var row = 0; row < table.rows.length; row++) {
for(var col = 0; col < widths.length; col ++) {
table.rows[row].cells[col].style.width = widths[col] + "px";
}
}
}
function max(num1, num2) { return (num1 > num2) ? num1 : num2; }
Я только что собрал плагин jQuery, который делает именно то, что вы хотите. Он очень маленький по размеру и действительно прост в реализации.
Все, что требуется, - это таблица, в которой есть thead и tbody.
Вы можете обернуть эту таблицу в DIV именем класса, и размер таблицы всегда будет изменяться в соответствии с этим div. так, например, если ваш div масштабируется с окном браузера, то будет и таблица. Заголовок будет исправлен при прокрутке. Нижний колонтитул будет исправлен (если вы включите нижний колонтитул). У вас также есть возможность клонировать заголовок в нижнем колонтитуле и исправить его. Кроме того, если вы сделаете окно браузера слишком маленьким и все столбцы не смогут поместиться... оно также будет прокручиваться горизонтально (заголовок тоже).
вы просто передаете имя класса DIV плагину следующим образом: $('.myDiv').fixedHeaderTable({footer: true, footerId: 'myFooterId'}); и плагин сделает все остальное. FooterID - это элемент на странице, который содержит разметку для вашего нижнего колонтитула. это используется, если вы хотите иметь в качестве нижнего колонтитула нумерацию страниц.
Если у вас есть несколько таблиц на странице, это также будет работать для каждой таблицы, для которой вы хотите иметь фиксированный заголовок.
проверить это здесь: http://fixedheadertable.mmalek.com/
Имейте в виду, что это все еще "бета", поэтому я ежедневно добавляю новые функции и исправления ошибок.
Поддерживаемые браузеры: IE6, IE7, IE8, FireFox, Safari и Chrome
Решение действительно простое. Вам нужно 3 DIV: общий контейнер (в моем случае класса "external"), контейнер таблицы (в моем случае класса "inner") и DIV, в котором вы делаете клон существующей таблицы, используя jQuery или javaScript (в моем случае класс "заголовок").
Решение использует CSS и несколько строк кода jQuery, который клонирует HTML "inner" в "header" и устанавливает его ширину и высоту. Поддерживает фиксированную и переменную ширину столбцов. Протестировано с IE8, Firefox 9, Safari и Google Chrome.
Вот пример кода:
$(document).ready(function() {
$('.header').html( $('.inner').html() );
$('.header').css('width', $('.inner table').outerWidth() );
$('.header').css('height', $('.inner table thead').outerHeight() );
});
table {
width:100%;
}
th {
border-top:1px solid #999;
text-align:left;
}
td, th {
border-bottom:1px solid #999;
background-color:#EEE;
}
.outer {
position:relative;
width:500px;
}
.inner {
height:150px;
overflow:auto;
}
.header {
position:absolute;
top:0;
left:0;
overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="outer">
<div class="inner">
<table cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>2</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>3</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>4</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>5</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>6</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>7</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>8</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>9</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>10</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>11</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>12</td><td>b</td><td>c</td><td>d</td></tr>
</tbody>
</table>
</div>
<div class="header">
</div>
</div>
</body>
Вы должны будете поместить заголовок вне прокручиваемого div. Все внутри div будет прокручиваться.
РЕДАКТИРОВАТЬ
Что касается ширины, если вы идете для отдельного заголовка, я вижу несколько решений:
- Предполагая, что это динамическое содержимое, генерируйте "фиксированную" ширину на основе длины строки. Очевидно, укажите в терминах EM и оставьте некоторый запас для ошибки.
- Используйте JavaScript.
- Используйте столбцы фиксированной ширины.
Я на самом деле не пробовал первый, и это может немного усложнить ситуацию. Это то, что нужно попробовать, если вы отчаянно нуждаетесь в эффекте.
Я должен также упомянуть, что, вероятно, есть библиотеки javascript с табличными виджетами, которые уже делают это. Посмотрите на них, чтобы увидеть, как они это делают.
Вы можете попробовать плагин jQuery Stupid Fixed Header. Техника в основном та же: клонировать заголовок и поместить его поверх слоя таблицы.
Вот хорошее решение (в основном CSS), которое использует столбцы фиксированной ширины: http://www.imaputz.com/cssStuff/bulletVersion.html
А вот немного кода jQuery для исправления ширины ячеек, когда содержимое ячейки занимает больше ширины, чем фиксированная ширина:
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"
type="text/javascript"></script>
<script>
$(function() {
$('div.tableContainer').each(function() { // for each table
var div = $(this);
var widths = [];
var changed = false;
$('table>*>tr', div).each(function(tr_i) {
$(this).children().each(function(i) {
var w = $(this).width();
if (w > widths[i]) {
widths[i] = w;
changed = true;
}
});
}).each(function(tr_i) {
if (changed)
$(this).children().each(function(i) {
var width = widths[i];
// add some width for scrollbar
if (tr_i == 0 && changed && i == widths.length-1) width += 16;
// insert a div to ensure width
$(this).append('<div style="width:'+width+'px; height:0px"> </div>');
});
});
div.width(div.children('table').width()).css('overflow-x', 'hidden');
});
});
</script>
Вывод немного отключен в IE при использовании нестрогого DTD. Настройте ширину в CSS, если вы не можете использовать стандартный режим.
Обратите внимание, что код jQuery увеличивает ширину таблицы в конце и отключает горизонтальную полосу прокрутки. Вы можете или не можете этого хотеть.
То, что вы действительно хотите сделать, это сделать <tbody>
таблицы данных с возможностью прокрутки, поэтому <thead>
а также <tfoot>
останется естественным образом исправленным.
Хотя это тривиально для FF и соавторов:
tbody
{
height: 100px; /* or whatever */
overflow: auto;
overflow-y: auto;
overflow-x: hidden;
}
IE имеет серьезные и сложные проблемы с телом в целом. Это можно решить с помощью выражений, но это нетривиально и специфично для дизайна.
Вам нужно поместить таблицу с заголовками о вашей таблице данных. Вы можете поддерживать ширину столбца с помощью таблицы-макета: исправлено. JavaScript может использоваться, чтобы соответствовать ширине столбца.
Взгляните на таблицу данных YUI, если вы ищете комплексную кросс-браузерную реализацию. Я считаю, что это делается путем создания другой таблицы с соответствующей шириной столбца.
Кажется, есть хитрости, необходимые для исправления ширины столбца. Если я правильно помню, Firefox требует наличия тегов
В любом случае, в YUI Data Table было много трюков (50 тыс. Строк). Вам бы посоветовали взглянуть на это и решить, как далеко вы хотели бы пройти самостоятельно.
Это решение работает с использованием CSS в Firefox и других браузерах Gecko, а также выражений CSS в IE.
http://home.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html
Верхний и нижний колонтитулы не остаются фиксированными в Opera или Safari/Chrome, но всю таблицу можно прокручивать, чтобы ее можно было использовать. Обратите внимание, что столбцы имеют процентную ширину в примере автора, но их можно удалить.
Если вы хотите поэкспериментировать с поддержкой Opera / Safari/Chrome, посмотрите на отображение блока tbody:block и перейдите оттуда.
Я не проверял это, но, возможно, вы могли бы сгенерировать таблицу дважды, один раз в заголовке и один раз в блоке прокрутки. Затем в заголовке сделайте все строки, кроме строки заголовка, невидимыми. Возможно, с помощью display: none или установите их высоту на ноль.