Подтвердить что ты не робот

Как создать строки заголовков фиксированных таблиц, которые включают colspans?

У меня есть большая динамическая таблица, созданная из данных базы данных. Мне нужно, чтобы строки заголовка столбцов оставались фиксированными и прокручивали нужные строки.

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

вот что я работаю с:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Sample</title>
  </head>

  <body>
    <br><br><br><br>

    <table id="A" border="0" width="95%" cellspacing="0" cellpadding="0" align="center" class="base">
      <tr bgcolor='gray'>
        <td>
          <br><br><br>
          need the blue column heading rows to remain fixed, and scroll the green rows:<br>

    <table id="XYZ" border="1" width="625" cellspacing="0" cellpadding="0" align="center" class="base">
      <thead>

        <tr>
          <th width="50px" bgcolor="DeepSkyBlue" align="center" valign="middle">Col 1a</th>
          <th width="50px" bgcolor="DeepSkyBlue" align="center" valign="middle">Col 1b</th>
          <th width="75px" bgcolor="DeepSkyBlue" align="center" valign="middle">Col 1c</th>
          <th width="100px" style="border-left:medium solid black;" colspan="3" bgcolor="DeepSkyBlue" align="center" valign="middle"><b>Col 2</th>
          <th width="100px" style="border-left:medium solid black;" colspan="1" bgcolor="DeepSkyBlue" align="center" valign="middle"><b>Col 3</th>
          <th width="150px" style="border-left:medium solid black;" colspan="5" bgcolor="DeepSkyBlue" align="center" valign="middle"><b>Col 4<br>more<br>more</th>
          <th width="100px" style="border-left:medium solid black;" colspan="1" bgcolor="DeepSkyBlue" align="center" valign="middle"><b>Col 5</th>
        </tr>
        <tr>
            <th bgcolor="DeepSkyBlue" colspan="3" align="center" valign="middle">Col 1</th>
            <th bgcolor="DeepSkyBlue" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <th bgcolor="DeepSkyBlue" align="center" valign="middle">B</th>
            <th bgcolor="DeepSkyBlue" align="center" valign="middle">C</th>
            <th bgcolor="DeepSkyBlue" style="border-left:medium solid black;" align="center">1</th>
            <th bgcolor="DeepSkyBlue" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <th bgcolor="DeepSkyBlue" align="center" valign="middle">4-b</th>
            <th bgcolor="DeepSkyBlue" align="center" valign="middle">4-c</th>
            <th bgcolor="DeepSkyBlue" align="center" valign="middle">4-d</th>
            <th bgcolor="DeepSkyBlue" align="center" valign="middle">4-e</th>
            <th bgcolor="DeepSkyBlue" style="border-left:medium solid black;" align="center">Z</th>
        </tr>
      </thead>
      <tbody>
        <tr>
            <td bgcolor="PaleGreen" colspan="3" align="center" valign="middle">Col 1<br>more</td>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">B</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">C</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[1]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="LimeGreen" align="center" valign="middle">Col 1a</td>
            <td bgcolor="LimeGreen" colspan="2" align="center" valign="middle">Col 1b+c</td>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">B</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">C</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[2]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="PaleGreen" colspan="2" align="center" valign="middle">Col 1a+b</td>
            <td bgcolor="PaleGreen" align="center" valign="middle">Col 1c</td>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">B</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">C</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[3]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="LimeGreen" align="center" valign="middle">Col 1a</td>
            <td bgcolor="LimeGreen" colspan="2" align="center" valign="middle">Col 1b+c<br>more</td>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">B</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">C</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[4]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="PaleGreen" colspan="2" align="center" valign="middle">Col 1a+b</td>
            <td bgcolor="PaleGreen" align="center" valign="middle">Col 1c</td>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">B</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">C</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[5]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="LimeGreen" align="center" valign="middle">Col 1a</td>
            <td bgcolor="LimeGreen" colspan="2" align="center" valign="middle">Col 1b+c</td>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">B</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">C</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[6]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="PaleGreen" colspan="2" align="center" valign="middle">Col 1a+b</td>
            <td bgcolor="PaleGreen" align="center" valign="middle">Col 1c</td>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">B</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">C</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[7]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="LimeGreen" align="center" valign="middle">Col 1a</td>
            <td bgcolor="LimeGreen" colspan="2" align="center" valign="middle">Col 1b+c<br>more<br>more</td>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">B</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">C</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[8]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="PaleGreen" colspan="2" align="center" valign="middle">Col 1a+b</td>
            <td bgcolor="PaleGreen" align="center" valign="middle">Col 1c</td>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">B</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">C</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[9]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="LimeGreen" align="center" valign="middle">Col 1a</td>
            <td bgcolor="LimeGreen" colspan="2" align="center" valign="middle">Col 1b+c<br>more<br>more</td>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">B</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">C</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="LimeGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="LimeGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[8]" size="3"></th>
        </tr>
        <tr>
            <td bgcolor="PaleGreen" colspan="2" align="center" valign="middle">Col 1a+b</td>
            <td bgcolor="PaleGreen" align="center" valign="middle">Col 1c<br>more<br>more<br>more<br>more<br>more<br>more<br>more<br>more<br>more<br>more</td>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">A</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">B</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">C</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center">1</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center" valign="middle">4-a</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-b</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-c</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-d</th>
            <td bgcolor="PaleGreen" align="center" valign="middle">4-e</th>
            <td bgcolor="PaleGreen" style="border-left:medium solid black;" align="center"><input type="text" NAME="b[9]" size="3"></th>
        </tr>
      </tbody>
    </table>

          <br><br><br><br>
        </td>
      </tr>
    </table>

    <br><br><br><br><br><br>

  </body>

</html>
4b9b3361

Ответ 1

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

Ниже все работает отлично в IE9, FF14.01 и Chrome 20.0.1132.57.

<table border="1">
    <colgroup>
        <td width="100px">Column 1</td>
        <td width="100px">Column 2</td>
        <td width="100px">Column 3</td>
        <td width="16px" style="background-color: gray;"><td>
    </colgroup>
</table>
<div style="position: absolute; height:75px; overflow-y:scroll; overflow-x:auto">
    <table border="1">
        <colgroup>
            <td width="100px"></td>
            <td width="100px"></td>
            <td width="100px"></td>
        </colgroup>
        <tbody>
            <tr>
                <td>Row 1 - Cell 1</td>
                <td>Row 1 - Cell 2</td>
                <td>Row 1 - Cell 3</td>
            </tr>
            <tr>
                // rest omitted, see DEMO for full table
            </tr>
        </tbody>
    </table>
</div>

См. DEMO

Изменить - 3 августа 2012

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

См. DEMO

Он чувствует себя немного хакерским, и я уверен, что есть правильное решение, но, похоже, оно работает хорошо. Тем временем.

Изменить - 7 августа 2012

Есть ли способ "вставить" всю эту таблицу в 100% ширина экрана и изменение высоты для высоты: 150 пикселей; к чему-то более динамичный, например $(window).height() - 200

Конечно, это более элегантный способ сделать это, но я смог сделать таблицу более динамичной.

Ширина была меньше из-за проблемы, так как я закрыл ширину тона около 95% и зафиксировал таблицу (-ы) при min-width: 600px; для заголовка и min-width: 584px для тела, тем самым обеспечив таблицу всегда выравнивается.

Для динамической высоты я использовал jQuery, привязывая функцию изменения размера к событию изменения размера окна:

$(document).ready(function() {
    resizeTableHeight();

    $(window).on("resize.resizeTableHeight", function() {
        resizeTableHeight();
    });
});

function resizeTableHeight() {
    var headerHeight = $("#tableHeaderContainer").height();
    var documentHeight = $(document).height();
    var spacingHeight = 50;

    $("#tableBodyContainer").height(documentHeight - headerHeight - spacingHeight);
}​

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

Do not забыть отменить это событие, когда вы не показываете сетку, поскольку она все равно будет выполняться при изменении размера каждый раз.

См. динамическую сетку DEMO

Вы заметите, что некоторые стили находятся в css (вверху справа) в скрипке, а другие - нет. Мой CSS не очень силен, и некоторые стили, когда я перемещал их из элементов в область CSS, начали истощаться. Я перешел в CSS, что мог, и оставил остальное жестко закодированным, чтобы не сломать его. Я уверен, что кто-то, кто работает с CSS каждый день, сможет разобраться в этом.

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

Резюме
Я уверен, что есть более элегантный способ добиться того, чего вы хотите, и, возможно, у какого-то script -wiz есть плагин для него. До тех пор это кажется сработавшим. Также может случиться так, что столбцы начнут пропускать выравнивание близко к 600 пикселям снова, если в столбцы введено много длинных данных, но, как указано, это очень персонализированное решение, и вам может потребоваться добавить некоторые динамические вычисления для некоторой ширины с jQuery с течением времени.

Изменить - 9 августа 2012

Относительно установки ширины td, указанной в комментариях. Я исправил проблему с длинным текстом в первом столбце, используя классы, о которых я упоминал. Работает в IE, FF и Chrome.

См. DEMO

Я использовал логику, упомянутую в комментариях. Вы можете найти гораздо лучшее соглашение об именах. Я просто использовал переключатель main-column + a on/off для каждого столбца. это выглядит следующим образом для стилей столбца 1:

.col01-000{
    width: 0px;
}
.col01-001{
    width: 75px;
}
.col01-010, .col01-100{
    width: 50px;
}
.col01-011, .col01-101{
    width: 125px;
}
.col01-110{
    width: 100px;
}

Я назначил первый td класс col01-100, что означает 50px.
Второй td теперь имеет класс col01-011, что указывает на то, что td все еще принадлежит к первому главному столбцу, но имеет ширину подкласса 2 (50px) и 3 (75px). Это составляет до 125 пикселей.

Надеюсь, это имеет смысл, но если я не с удовольствием продолжу обсуждение в чате и буду работать с вами, если это то, что вы хотите применить.

Пока я вижу измерения:

Col01

  • Col1 = colspan 3 over 175px
  • 3 Суб-столбцы, разбивающие 175px вниз следующим образом: 50px-50px-75px

Col02

  • Col2 = colspan 3 более 100px
  • 3 Суб-столбцы, разбивающие 100 пикселей вниз следующим образом: 40px-30px-30px

Col03

  • Col3 = colspan 1 более 100px
  • Без подклассов

Col04

  • Col4 = colspan 5 более 150px
  • 5 суб-столбцов, разбивающих 150 пикселей вниз следующим образом: 30px-30px-30px-30px-30px

Col05

  • Col5 = colspan 1 более 100px
  • Без подклассов

Ответ 2

Изменить: Исправить фиксированную позицию при изменении размера окна:

http://jsfiddle.net/eReBn/13/

Полный код:

$(function() {
    (function($) {
        $.fn.fTable = function(o) {

            var tableTmpl = '<table id="XYZ_fixed" border="1" width="625" cellspacing="0" cellpadding="0" align="center" class="base"></table>';

            this.wrap('<div class="fTable_container" />');
            var fc = this.parent();
            fc.css('width', this.width() + 18);

            this.wrap('<div class="fTable_rContainer" />');
            var rc = this.parent();
            rc.css('height', o.height);

            var fTable = $(tableTmpl);
            fTable
             .addClass('fTable_fixedHead')
             .html(this.find('thead').clone())
             .prependTo(rc);

            $(window).on('scroll resize', function () {
                console.log(isScroll());
                if (isScroll()) {
                    fTable.css('left', $(this).scrollLeft() * -1);
                } else {
                    fTable.css('left', '');
                }
            });
        };

        function isScroll() {
           var root= document.compatMode=='BackCompat'?
               document.body : document.documentElement;
            return root.scrollWidth>root.clientWidth;
        }

    })(jQuery);

    $('#XYZ').fTable({
        height: 300
    });
});

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

DEMO: http://jsfiddle.net/eReBn/12/embedded/result/

Ручной режим:

а. Скопируйте ниже CSS в таблицу стилей

.fTable_rContainer {
    position: relative;
    overflow: auto;    
    height: 300px; /* Height of the table */
}

.fTable_container {
    width: 643px;  /* Total width of the table you set + 18px (scroll size) */
}

.fTable_fixedHead {
    position: fixed; 
}

б. Оберните таблицу с помощью div class="fTable_container"

с. Скопируйте часть thead исходной таблицы и перейдите в новую таблицу, как в DEMO.

д. Добавить класс fTable_fixedHead в новую таблицу

Автоматизировано с помощью некоторых скриптов:

DEMO: http://jsfiddle.net/eReBn/11/embedded/result/


Я попытался решить его, используя 2 таблицы,

  • Оригинальная таблица (нетронутая)
  • Фиксированная таблица заголовков (абсолютная позиция) над исходной таблицей

Проверьте это и дайте мне знать, если вам это нравится.

DEMO

Протестировано в Firefox и Chrome. [Будет проверено позже в других браузерах]

Полный код @http://jsfiddle.net/eReBn/7/

JS:

$(function() {
   (function($) {
     $.fn.fTable = function(o) {
        /* Preserve the attr list from original table    */
        var el = this[0], arr = [], it;
        for (var i = 0, attrs = el.attributes, l = attrs.length; i < l; i++) {

          it = attrs.item(i);

          if (it.nodeName == 'id') {
           arr.push(it.nodeName + '="' + it.nodeValue + '_fixed"');
          } else {
           arr.push(it.nodeName + '="' + it.nodeValue + '"');
          }
        }

        var tableTmpl = '<table ' + arr.join(' ') + '></table>';

        /* Wrap it inside div */
        this.wrap('<div class="fTable_container" />');
        this.wrap('<div class="fTable_rContainer" />');

        var rc = this.parent();

        /* Clone the thead and add it to the fixed table head */
        $(tableTmpl)
          .addClass('fTable_fixedHead')
          .html(this.find('thead').clone())
          .prependTo(rc);

        /* Position the fixed head table on scroll */
        rc.scroll(function() {
          rc.find('.fTable_fixedHead').css('top', $(this).scrollTop());
        });

        var _that = this;
        rc.find('.fTable_fixedHead').css('left', _that.aPosition().left);

        /* Position the left on resize*/
        $(window).resize(function() {
          rc.find('.fTable_fixedHead').css('left', _that.aPosition().left);
        });
     };

     /* Position fix for webkit browsers */
     jQuery.fn.aPosition = function() {
        thisLeft = this.offset().left;
        thisTop = this.offset().top;
        thisParent = this.parent();
        parentLeft = thisParent.offset().left;
        parentTop = thisParent.offset().top;
        return {
           left: thisLeft - parentLeft,
           top: thisTop - parentTop
        }
     }
  })(jQuery);      

});

Применение:

$('#XYZ').fTable({
    height: 300
});

Ответ 3

Мы использовали DataTables.net и решили очень похожую проблему довольно хорошо. Вот example со своего веб-сайта с расширенным многострочным заголовком. Вы также можете сортировать свои категории подкатегорий.

Ответ 4

Я также могу предоставить вам вариант. Это предполагает, что окно браузера прокручивается.

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

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

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

jsFiddle DEMO

$(function(){
    var $window = $(window),
        stickyTable = $('#XYZ'),
        stickyHeader = stickyTable.clone(true),
        tableTop = stickyTable.offset().top,
        isSticky = false;

    handleScroll();

    $window.on({
        scroll: handleScroll,
        resize: handleResize
    });


    stickyHeader.find('tbody').remove();
    stickyHeader.find('tfoot').remove();

    stickyHeader.addClass('sticky-header').appendTo('body');

    function handleScroll() {
        var scrollTop = $window.scrollTop();

        if(scrollTop > tableTop && !isSticky) {
            stickyHeader.css('left',stickyTable.offset().left+'px').show();
            isSticky = true;
        } else if(scrollTop <= tableTop && isSticky) {
            stickyHeader.hide();
            isSticky = false;
        }
    }

    function handleResize() {
        if(isSticky) {
            stickyHeader.css('left',stickyTable.offset().left+'px');
        }
    }
});​

Ответ 5

Если вы . clone() thead и поместите его в таблицу, все столбцы сохраняют свою первоначальную ширину.

Обновление: Я понял, что у IE 6 и 7 возникли проблемы, и я их исправил. Проблема заключалась в том, что эти версии IE не позволяют напрямую позиционировать thead. В результате я изменил его так, что вместо него он перемещает thead tr, но только если браузер IE и lt; 8.

Другая ошибка заключалась в том, что IE < 9 были проблемы с .prependTo(). Я не уверен, что это только тестер IE или нет, но я решил проблему, используя .after().

Обновлено демо

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
  // http://obvcode.blogspot.com/2007/11/easiest-way-to-check-ie-version-with.html
  var Browser = {
    version: function() {
    var version = 999; // we assume a sane browser
      if (navigator.appVersion.indexOf("MSIE") != -1) {
        // bah, IE again, lets downgrade version number
        version = parseFloat(navigator.appVersion.split("MSIE")[1]);
      }

      return version;
    }
  }

  var $thead = $('#XYZ thead'),
      $new_thead = $thead.clone().hide(),
      $window = $(window),

      distance_from_top = $thead.offset().top,
      did_scroll = false; // http://ejohn.org/blog/learning-from-twitter/

  // for IE <= 7
  var $tr_1, $tr_2;

  // add the cloned thead
  $thead.after($new_thead);

  if( Browser.version() < 8 ) {
    $new_thead.find('tr').css({
      'position': 'absolute',
      'top': 0,
      'margin-left': -1
    });

    $tr_1 = $new_thead.find('tr:first');
    $tr_2 = $new_thead.find('tr:last').css('top', $tr_1.height());
  }else {
    $new_thead.css({
    'position': 'fixed',
    'width': $thead.width(),
    'top': 0
    });
  }

  $window.scroll(function() {
    if( Browser.version() < 8 ) {
      did_scroll = true;
    }

    if( $window.scrollTop() >= distance_from_top ) {
      $new_thead.show();
    }else {
      $new_thead.hide();
    }
  });

  setInterval(function() {
    if( did_scroll ) {
    did_scroll = false;
      $tr_1.css('top', $window.scrollTop());
      $tr_2.css('top', $tr_1.height() + $window.scrollTop());
    }
  }, 250);
</script>

Изменить

Я не понимал, что K.M. требуется таблица с фиксированной высотой. Если вы посмотрите на мой пример выше, вы увидите, что заголовок таблицы исправлен, если браузер прокручивается в верхней части таблицы. Однако, по моему мнению, это не то, что он/она хотел.

Я тестировал это в следующих браузерах на моем Mac.

  • Safari (5.1.7)
  • Firefox (11.0)
  • Chrome (21.0.1180.75)

И я тестировал это в Windows 7 с помощью:

  • IE 8 и 9 с помощью тестера IE
  • Firefox (5.0.1, 6.0.2, 7.0.1, 8.0.1, 10.0.2)
  • Chrome (12.0.742.91)
  • Safari (5.1.5)

Он разбит в IE 6 и 7, но я не смотрел, было ли исправление.

Демо


var table = $('#XYZ'),
    thead = table.find('thead'),
    fixed_thead = thead.clone(),

    // create a copy of the original table
    fixed_thead_wrapper = $('<table />', {
      'id': 'fixed_thead_wrapper',
      'align': 'center',
      'width': table.outerWidth(),
      'border': '1',
      'cellspacing': 0,
      'cellpadding': 0              
    }).insertBefore(table),

    // this forces the table to be in a scrollable area
    table_wrapper = $('<div />', {
      'id': 'fixed_table_wrapper',
      'height': 300,
      css: {
        'overflow': 'auto'
      }
    });

// add the cloned thead to the new table
fixed_thead_wrapper.append(fixed_thead);

// hide the original thead.
// this is a very hackish way of doing this, but I'm not sure of a better way as of right now
table.css({
  'position': 'relative',
  'top': fixed_thead_wrapper.height() * -1
});

// wrap the original table
table.wrap(table_wrapper);

// line the tables up now that the scrollbar is present
fixed_thead_wrapper.css({
  'position': 'relative',
  'left': table.offset().left - fixed_thead_wrapper.offset().left
});

Ответ 6

Некоторые из ранее написанных ответов были блестящими!!

Я тестировал это в Google Chrome большую часть времени из-за блестящих инструментов разработчика Chrome для отладки Javascript на лету и настройки CSS в реальном времени.

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

Следующий код будет клонировать заголовок таблицы:

jQuery(document).ready(function () {
    jQuery("body").append("<table class='tableheader' align='center' border='1' width='625' cellspacing='0' cellpadding='0'></table>");
    jQuery(".tableheader").append(jQuery(".base2 thead").clone());

Затем вам нужно установить некоторую статическую переменную и уловить событие прокрутки:

var headerToMove = jQuery(".tableheader");
var headerOffsetTop = headerToMove.offset().top;
var headerPosition = headerToMove.position();

jQuery(window).scroll(function () { scroll_post_header(); });

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

    function scroll_post_header() {
        var new_position = headerOffsetTop - jQuery(window).scrollTop();
        if (new_position < 0) { new_position = 0;}
        if (headerPosition.top != new_position) {
            headerToMove.css("top",new_position);
            //headerToMove.stop().animate({ 'top': new_position }, 300);
        }
        if (jQuery(window).scrollTop() < 15) { headerToMove.css("top",headerOffsetTop);}
    }
});

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

.tableheader {
    position: fixed;
    height: 80px;
    top: 160px;
    left: 2.5%;
    z-index: 1000;    
}

Полный рабочий пример можно найти по адресу: http://jsfiddle.net/webwarrior/YZ8cJ/142/

Надеюсь, что это поможет несколько, не меняя какой-либо html.

Ответ 7

Я всегда использовал этот супер простой в использовании плагин, который обрабатывает его так же легко, как $('#tableID').fixedtableheader();

Работает удивительно, очень легко и гибко.

http://fixedheadertable.com/

Ответ 9

Проверьте Fiddle

Вот код. Работает отлично во всех браузерах...!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Scrollable Table with Fixed Header</title>
<meta http-equiv="language" content="en-us">

<script type="text/javascript">
    function removeClassName (elem, className) {
        elem.className = elem.className.replace(className, "").trim();
    }

    function addCSSClass (elem, className) {
        removeClassName (elem, className);
        elem.className = (elem.className + " " + className).trim();
    }

    String.prototype.trim = function() {
        return this.replace( /^\s+|\s+$/, "" );
    }

    function stripedTable() {
        if (document.getElementById && document.getElementsByTagName) {  
            var allTables = document.getElementsByTagName('table');
            if (!allTables) { return; }

            for (var i = 0; i < allTables.length; i++) {
                if (allTables[i].className.match(/[\w\s ]*scrollTable[\w\s ]*/)) {
                    var trs = allTables[i].getElementsByTagName("tr");
                    for (var j = 0; j < trs.length; j++) {
                        removeClassName(trs[j], 'alternateRow');
                        addCSSClass(trs[j], 'normalRow');
                    }
                    for (var k = 0; k < trs.length; k += 2) {
                        removeClassName(trs[k], 'normalRow');
                        addCSSClass(trs[k], 'alternateRow');
                    }
                }
            }
        }
    }

    window.onload = function() { stripedTable(); }
</script>

<style type="text/css">

body {
    background: #FFF;
    color: #000;
    font: normal normal 12px Verdana, Geneva, Arial, Helvetica, sans-serif;
    margin: 10px;
    padding: 0
}

table, td, a {
    color: #000;
    font: normal normal 12px Verdana, Geneva, Arial, Helvetica, sans-serif
}

h1 {
    font: normal normal 18px Verdana, Geneva, Arial, Helvetica, sans-serif;
    margin: 0 0 5px 0
}

h2 {
    font: normal normal 16px Verdana, Geneva, Arial, Helvetica, sans-serif;
    margin: 0 0 5px 0
}

h3 {
    font: normal normal 13px Verdana, Geneva, Arial, Helvetica, sans-serif;
    color: #008000;
    margin: 0 0 15px 0
}

div.tableContainer {
    clear: both;
    border: 1px solid #963;
    height: 285px;
    overflow: auto;
    width: 756px
}

html>body div.tableContainer {
    overflow: hidden;
    width: 756px
}

div.tableContainer table {
    float: left;
    width: 740px
}

html>body div.tableContainer table {
    width: 756px
}

thead.fixedHeader tr {
    position: relative
}

html>body thead.fixedHeader tr {
    display: block
}

thead.fixedHeader th {
    background: #C96;
    border-left: 1px solid #EB8;
    border-right: 1px solid #B74;
    border-top: 1px solid #EB8;
    font-weight: normal;
    padding: 4px 3px;
    text-align: left
}

thead.fixedHeader a, thead.fixedHeader a:link, thead.fixedHeader a:visited {
    color: #FFF;
    display: block;
    text-decoration: none;
    width: 100%
}

thead.fixedHeader a:hover {
    color: #FFF;
    display: block;
    text-decoration: underline;
    width: 100%
}

html>body tbody.scrollContent {
    display: block;
    height: 262px;
    overflow: auto;
    width: 100%
}

tbody.scrollContent td, tbody.scrollContent tr.normalRow td {
    background: #FFF;
    border-bottom: none;
    border-left: none;
    border-right: 1px solid #CCC;
    border-top: 1px solid #DDD;
    padding: 2px 3px 3px 4px
}

tbody.scrollContent tr.alternateRow td {
    background: #EEE;
    border-bottom: none;
    border-left: none;
    border-right: 1px solid #CCC;
    border-top: 1px solid #DDD;
    padding: 2px 3px 3px 4px
}

html>body thead.fixedHeader th {
    width: 200px
}

html>body thead.fixedHeader th + th {
    width: 240px
}

html>body thead.fixedHeader th + th + th {
    width: 316px
}


html>body tbody.scrollContent td {
    width: 200px
}

html>body tbody.scrollContent td + td {
    width: 240px
}

html>body tbody.scrollContent td + td + td {
    width: 300px
}
</style>
</head><body>
<div id="tableContainer" class="tableContainer">
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="scrollTable">
<thead class="fixedHeader">
    <tr class="alternateRow">
        <th><a href="">Header 1</a></th>
        <th><a href="">Header 2</a></th>
        <th><a href="">Header 3</a></th>
    </tr>
</thead>
<tbody class="scrollContent">
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
        <td>End of Cell Content 1</td>
        <td>End of Cell Content 2</td>
        <td>End of Cell Content 3</td>
    </tr>
</tbody>
</table>
</div>
</body></html>

Ответ 10

У меня есть идея для вас. Вы разделите таблицу на две таблицы. Один из них будет выступать в качестве заголовка, а второй будет действовать как остальная часть всех ячеек и строк. Трюк в следующем: Размещение двух фиксированных ширины и высоты divs вертикально рядом с собой. верхний будет загружать таблицу заголовков, а n будет действовать ниже для тела таблицы. в нижнем div вы установите вертикальное переполнение. Таким образом, у вас будет простое решение, которое поддерживает перемещение заголовка с прокруткой данных.

Ответ 11

Кажется, лучший способ сделать это - две таблицы. Наружный стол с заголовками и одна большая строка с внутренним столом внутри. Div должен быть css'ed overflow: прокрутка или авто с заданной высотой (через css или javascript). Вам нужно будет установить определенную ширину для всех столбцов. Я думаю, что лучший способ сделать это - дать класс для каждого заголовка и убедиться, что соответствующие столбцы во внутренней таблице имеют одинаковые классы.

<table>
    <tr><th>...</th></tr>
    <tr><td>
            <div><inner table></div>
    </td></tr>
</table>

Проверьте это на примерах: http://www.cssplay.co.uk/menu/tablescroll.html

Ответ 12

Очень быстрая и отрывочная, но, надеюсь, вы получите идею, почему бы просто не использовать position:fixed для thead. jsfiddle: http://jsfiddle.net/b3S5F/