Прокрутка таблицы с несколькими фиксированными заголовками таблицы

#javascript #jquery #scroll #html-table

#javascript #jquery #прокрутка #html-таблица

Вопрос:

Прежде чем я попытаюсь изобрести колесо (с помощью плагина jQuery или аналогичного), я пытаюсь выяснить, есть ли более простой способ сделать это или существующий плагин, о котором пользователи могут знать. Что я хочу сделать, так это прокрутить тело таблицы, содержащей несколько заголовков таблицы. Например, представьте что-то вроде этой структуры:

 <table>
    <thead>
        <tr>
            <td colspan="2"></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </tbody>
    <thead>
        <tr>
            <td colspan="2"></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td></td>
        </tr>
        <tr>
           <td></td>
           <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>
  

Честно говоря, я не пробовал приведенный выше синтаксис, чтобы даже посмотреть, действителен ли он. Фактическая разметка, которая у меня есть, в настоящее время не использует ad / tbody и вместо этого прокручивает весь родительский div (см. Ниже).

пример таблицы с несколькими заголовками

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

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

Комментарии:

1. Это довольно специализированный случай — возможно, это было сделано раньше, но я сомневаюсь, что вы найдете существующий плагин. Вы просто ищете ответы, которые укажут вам на существующий плагин, или вы ищете помощи в «изобретении колеса»?

2. вот плагин jquery для липкого заголовка polarblau.github.com/stickySectionHeaders но это для списка ‘ul’, а не для таблицы. Этот пример тоже может вам помочь jsfiddle.net/6qqPz

3. @satrun77: Спасибо, это действительно выглядит действительно интересно. Может быть что-то там.

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

Ответ №1:

Несколько месяцев назад я написал некоторый код, который делал именно то, что я хотел, чтобы заголовки выполнялись аналогично заголовкам разделов на iOS. Используя Jquery, решение, к которому я пришел, включало создание прослушивателя событий onScroll (и OnResize для изменения размера окна), который проверял все $('table thead') и проверял их $(this).position() на странице.

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

Как только я нашел наиболее подходящий заголовок (самый нижний, thead который находился над окном просмотра), я создал новый, table с position: fixed значением (0, 0) и скопировал в него новый столбец для каждого столбца строк заголовков и вручную установил его width свойства в соответствии с исходной таблицей.

Я собрал доказательство концепции, которое показывает, как все это работает.

Вот некоторый псевдокод того, как это работает:

  1. Проверьте, видна ли таблица
  2. Получить список всех thead разделов в таблице
  3. Переверните список
  4. Найдите первый thead в массиве с верхней позицией меньше, чем scrollTop от body элемента
  5. Если мы нашли один:
    1. Создайте глубокую копию thead
    2. Создайте таблицу-контейнер
    3. Скопируйте атрибуты из исходной таблицы, чтобы стили были скопированы
    4. Расположите контейнер в [0, originalTable.left]
    5. Установите ширину, равную outerWidth исходной таблице
    6. Установите ширину каждого td найденного элемента на ширину соответствующего элемента td из исходной таблицы
    7. Добавьте его в DOM
  6. Если ничего не найдено, удалите существующий контейнер из DOM, если он там был

Есть некоторые другие детали edge case, которые сделали это еще приятнее:

  • Вместо (0, 0) исходная точка для фиксированной строки была изменена в зависимости от того, должна ли «реальная» строка заголовка для tbody ниже строки с фиксированным заголовком отталкивать ее.
  • Убедитесь, что предыдущие строки заголовка удалены, прежде чем создавать новую
  • Не создавайте заново строку заголовка, если создаваемый вами заголовок совпадает с тем, что уже есть

Этот подход работал намного лучше других, которые я пробовал, таких как попытка position:absolute объекта из-за того, что Firefox и IE не очень быстро запускают обработчик onScroll, поэтому вы, как правило, видите «дрожание». Я также пытался использовать position атрибут thead s, это просто привело к скачку ширины столбцов таблицы и несоответствию данным.

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


Обновление: Добавлен пример кода и псевдокод Обновление: Dropbox изменил свою систему, заменил пример URL-адресом jsfiddle

Комментарии:

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

2. @Josh Да, бинго. Текст просто показывает, что заголовок исчезает, когда таблица не видна

3. @AlexTaylor Это довольно мило. Потрясающий пример / задание.

4. Это выглядит действительно красиво. Мне было бы интересно узнать, делали ли вы что-нибудь подобное без таблиц. Я ищу прокручивающийся div, где постоянными являются заголовки <h3> , а не заголовки таблицы.

5. @rybo111 смотрите комментарий satrun77 к вопросу, который указывает на плагин jQuery polarblau.github.com/stickySectionHeaders с примером: jsfiddle.net/6qqPz