Замороженный заголовок таблицы внутри прокручиваемого div

У меня три div. Заголовок, центральный и нижний колонтитул. Существует таблица в центральном div (gridview), которая почти всегда длиннее внешнего div. Поэтому я сделал этот div прокручиваемым по вертикали. Возникает вопрос: как я могу сделать заголовок таблицы, что он будет виден после прокрутки div? Я мог бы сделать этот заголовок с отдельными div или table и сделать его фиксированным, но ширина столбцов в таблице не всегда одинакова, поэтому я не знаю, как сохранить ширину столбцов в заголовке. Любая подсказка?

Ответ 1

Вот базовое решение, использующее 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; }

Ответ 2

Я только что собрал плагин jQuery, который делает именно то, что вы хотите. Его очень маленький по размеру и очень простой в использовании.

Все, что требуется, это таблица с ада и тэгом.

Вы можете обернуть эту таблицу в DIV с именем класса, и таблица будет всегда изменять размер, чтобы она соответствовала этому div. так, например, если ваши div-шкалы с окном браузера так будут отображаться в таблице. Заголовок будет фиксирован при прокрутке. Нижний колонтитул будет зафиксирован (если вы используете нижний колонтитул). У вас также есть возможность клонировать заголовок в нижнем колонтитуле и фиксировать его. Также, если вы сделаете окно браузера слишком маленьким, и все столбцы не могут поместиться... он также будет прокручиваться по горизонтали (заголовок тоже).

вы просто передаете имя класса DIV плагину так: $('. myDiv'). fixedHeaderTable ({footer: true, footerId: 'myFooterId'}); и плагин сделает все остальное. FooterID - это элемент на странице, содержащий надпись для нижнего колонтитула. это используется, если вы хотите иметь разбивку на страницы как нижний колонтитул.

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

проверьте здесь: http://fixedheadertable.mmalek.com/

Помните о своей "бета-версии", поэтому я ежедневно добавляю новые функции и исправления ошибок.

Поддерживаемые браузеры: IE6, IE7, IE8, FireFox, Safari и Chrome

Ответ 3

Решение действительно простое. Вам нужно 3 DIVs: общий контейнер (в моем случае класса "внешний" ), контейнер таблицы (в моем случае класса "внутренний" ) и DIV, в котором вы создаете клон существующей таблицы с использованием jQuery или javaScript ( в моем случае класса "header" ).

Решение использует CSS и несколько строк кода jQuery, который клонирует HTML "внутреннего" в "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>

Ответ 4

Вам нужно будет поместить заголовок вне прокручиваемого div. Все в пределах div будет прокручиваться.

ИЗМЕНИТЬ

Что касается ширины, если вы идете для отдельного заголовка, я вижу несколько решений:

  • Предполагая, что это динамический контент, генерируйте "фиксированные" ширины в зависимости от длины строки. Очевидно, укажите в терминах EM и оставьте некоторый запас за ошибку.
  • Используйте javascript.
  • Использовать столбцы с фиксированной шириной.

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

Я также должен упомянуть, что, вероятно, есть javascript-библиотеки с виджетами таблицы, которые уже делают это. Посмотрите на них, чтобы посмотреть, как они это делают.

Ответ 5

Вам нужно поставить таблицу с заголовками о вашей таблице данных. Вы можете сохранить ширину столбца с табличным макетом: исправлено. JavaScript может использоваться для соответствия ширине столбцов.

Ответ 6

Здесь хорошее решение (в основном 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">&nbsp;</div>');
      });
    });
    div.width(div.children('table').width()).css('overflow-x', 'hidden');
  });
});
</script>

В IE используется выходной сигнал при использовании нестрого DTD. Измените ширину в CSS, если вы не можете использовать режим стандартов.

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

Ответ 7

Вы можете попробовать плагин jQuery Stupid Fixed Header. Техника в основном такая же: клонировать заголовок и помещать его поверх слоя таблицы.

Ответ 8

То, что вы на самом деле хотите сделать, - это сделать <tbody> таблицы данных прокручиваемой, поэтому <thead> и <tfoot> останутся естественными.

Хотя это тривиально для FF и др.:

tbody
{
    height: 100px; /* or whatever */
    overflow: auto;
    overflow-y: auto;
    overflow-x: hidden;
}

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

Ответ 9

Я не тестировал это, но, возможно, вы могли бы сгенерировать таблицу дважды, один раз в заголовке и один раз в прокручиваемом div. Затем в заголовке сделайте все строки, кроме строки заголовка, невидимой. Возможно, с "display: none" или установите их высоту на ноль.

Ответ 10

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

Кажется, что для исправления ширины столбцов требуются трюки. Если я правильно помню, Firefox требует < col/ > теги, которые будут присутствовать.

В любом случае в YUI DataTable (50k строк) было много трюков. Вам было бы хорошо посоветовать посмотреть на это и решить, как далеко вы хотите пойти самостоятельно с этим.

Ответ 11

Это решение работает с использованием CSS в Firefox и других браузерах Gecko, а также в выражениях CSS в IE.

http://home.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html

Верхний и нижний колонтитулы не фиксируются в Opera или Safari/Chrome, но вся таблица прокручивается, поэтому ее можно использовать. Обратите внимание, что столбцам заданы процентные ширины в примере автора, но их можно удалить.

Если вы хотите поэкспериментировать с поддержкой Opera/Safari/Chrome, посмотрите на отображение tbody: block и оттуда.

Ответ 13

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

Проверьте это:

http://www.bobthegeek.com/?p=12

Боб