Сделать TBODY прокручиваемым в браузерах Webkit

Я знаю этот вопрос, но ни один из ответов не работает в Safari, Chrome и т.д.

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

<table>
    <thead>
        <tr><th>This is the header and doesn't scroll</th></tr>
    </thead>
    <tbody style="height:100px; overflow:auto;">
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
    </tbody>
</table>

К сожалению, это не работает ни в каких браузерах webkit. Существует отчет об ошибках об этом, который не кажется высоким приоритетом (сообщается в июне 05).

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

Ответ 2

Использование дисплея: стиль блока работает только в том случае, если у вас есть 1 столбец. Если у вас несколько столбцов данных - с несколькими полями - тогда отобразите: блок показывает, что все столбцы данных прокручиваются, но под 1-м столбцом (делает то же самое в Firefox - это единственный браузер, который я знаю, который отлично прокручивает прокрутку). Кстати, на Firefox - вы можете использовать стиль overflow-x: hidden для подавления горизонтальной прокрутки.

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

Ответ 3

Попробуйте первый метод этой страницы, чистый CSS с одной таблицей (2 divs вокруг таблицы, а thead - абсолютный): http://www.cssplay.co.uk/menu/tablescroll.html Кажется, для работы над FF4/IE9/IE8 в дополнение к IE7/FF3.6.

Ответ 4

У меня была такая же проблема, и я написал jQuery script, чтобы сделать это для меня... использует два элемента таблицы и соответственно форматирует css. Надеюсь, это поможет другим, у кого есть такая же проблема...

http://jsfiddle.net/pe295/1/

Ответ 5

Я видел Sean Haddy отличное решение и взял на себя внесение некоторых изменений:

  • Используйте классы вместо ID, поэтому один jQuery script может быть повторно использован для несколько таблиц на одной странице
  • Добавлена ​​поддержка семантических элементов таблицы HTML, таких как caption, thead, tfoot и tbody.
  • Сделана опция прокрутки, поэтому она не будет отображаться для таблиц, которые "короче", чем прокручиваемая высота.
  • Скорректированная ширина прокрутки div, чтобы довести панель прокрутки до правого края таблицы.
  • Доступная концепция
    • с помощью aria-hidden = "true" при вставке статического заголовка таблицы
    • и оставляя исходный код на месте, просто скрытый с jQuery и установите aria-hidden="false"
  • Показаны примеры нескольких таблиц разных размеров.
Однако Шон сделал тяжелый подъем. Благодаря Мэтту Бурланду тоже, чтобы указать на необходимость поддержки tfoot.

Пожалуйста, убедитесь сами в http://jsfiddle.net/jhfrench/eNP2N/

Ответ 6

A давно столкнулась с такой же проблемой, и я, наконец, изложил подход к двум таблицам. Это результат: http://jsfiddle.net/bGr4V/3/, он работает для всех браузеров (IE6 + вкл.).

В этот jsFiddle вы можете играть с чистой версией.

Моим решением было добавить ячейку fix <th class="fix"> </th> в thead, чтобы заполнить пробел полосы прокрутки в tbody, а затем дать одному столбцу переменную ширину (<td class="grow">), поэтому ячейка исправления заголовка не будет отменять изменение размера.

HTML:

<div class="fixed_table">
  <div class="head">
    <table>
      <thead>
        <tr>
          <th>Column header</th>
          <th class="grow">Column header</th>
          <th class="fix"> </th>
        </tr>
      </thead>
    </table>
  <div class="body">
    <table class="full_table">
      <caption class="caption">Caption</caption>
      <tbody>
        <tr>
          <td>Data</td>
          <td class="grow">Data</td>
        </tr>
        <tr>
          <td>...</td>
          <td>...</td>
        </tr>
        <tr>
          <td>...</td>
          <td>...</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

CSS: имеет * и _ взломать для ie6-7, а -webkit, специфичный для ширины прокрутки, подходящей для фиксирующей ячейки заголовка, в каждом случае.

.fixed_table table {
  table-layout: fixed;
  width: auto;
  border-width: 0;
  padding: 0;
  border-collapse: collapse;
}

.fixed_table .body {
  overflow: scroll;
  overflow-x: hidden;
  max-height: 10.75em;
  min-height: 2.5em;
  padding-bottom: 0.8em;
  *padding-right: 17px; /*ie7 & ie6*/
  _padding-right: 0; /*ie6*/
  _height: 10em ;
}

.fixed_table th, .fixed_table td {
  width: 4.7em;
}

.fixed_table .grow {
  width: auto;
}

.fixed_table .fix {
  width: 16px;
  *width: 17px; /*ie7 & ie6*/
  _width: 16px; /*ie6*/
}

/* webkit specific */
@media screen and (-webkit-min-device-pixel-ratio:0) {
  .fixed_table .fix{ width: 17px }
}

Ответ 7

Думал, что я брошу свое решение в микс - http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/.

Он принимает тот же базовый маршрут, что и решение @Michael Koper, но включает обходной путь, поэтому таблица будет выглядеть корректно в IE обратно в IE6.

Я решаю проблему ширины, предоставляя <table> a table-layout: fixed и явно назначая ширину ячейкам в каждом столбце. Не идеально, но он создает семантическую таблицу, которая будет выравнивать кросс-браузер независимо от того, нужна ли полоса прокрутки.

Демо: http://codepen.io/tjvantoll/pen/JEKIu

Ответ 8

Я разработал решение javascript для вышеупомянутой проблемы
который работает только в Firefox 7+, поскольку я тестировал только в FF
Я пришел к этой теме и нашел решение, указанное Michael Koper

В этом решении делаются три важные вещи
1) исправьте ширину столбца
2) для параметра thead > tr установлено значение block 3) дисплей tbody установлен на блокировку

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

поэтому я думал, что буду фиксировать ширину динамически (после того, как таблица будет отображаться в браузере) и это сделало трюк:)

следующее - это решение в javascript, которое работает только в FF (я тестировал только в FF, у меня нет доступа к другим браузерам)

       function test1(){                
            var tbodys = document.getElementsByTagName("TBODY");
            for(var i=0;i<tbodys.length;i++){
                do_tbodyscroll(tbodys[i]);
            }
        }


      function do_tbodyscroll(_tbody){
            // get the table node 
            var table = _tbody.parentNode;

            // first row of tbody 
            var _fr = _tbody.getElementsByTagName("TR")[0];

            // first row cells .. 
            var _frcells = _fr.cells;

            // Width array , width of each element is stored in this array 
            var widtharray = new Array(_frcells.length);

            for(var i=0;i<_frcells.length;i++){                    
                widtharray[i] = _frcells[i].scrollWidth;
            }                

            // Apply width to first row                  
            for(var i=0;i<_frcells.length;i++){
                _frcells[i].width = widtharray[i];                   
            }                 

            // Get the Last row in Thead ... 
            // COLGROUPS USING COLSPAN NOT YET SUPPORTED

            var thead = table.getElementsByTagName("THEAD")[0];
            var _rows = thead.getElementsByTagName("TR");
            var tableheader = _rows[_rows.length - 1];
            var headercells = tableheader.cells;

            // Apply width to header ..                                
            for(var i=0;i<headercells.length;i++){
                headercells[i].width = widtharray[i];
            }

            // ADD 16 Pixel of scroll bar to last column ..
            headercells[headercells.length -1 ].width = widtharray[headercells.length -1] + 16;

            tableheader.style.display = "block";
            _tbody.style.display = "block";  
        }

В этом решении выясняется, что такое ширина столбца из браузера
и снова установите ту же ширину в столбцы (заголовок и первая строка tbody)
после установки ширины; на дисплее thead > tr и tbody установлено значение

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

Ответ 9

Это действительно довольно хаки, но, возможно, это поможет кому-то...

http://jsfiddle.net/yUHCq/1/

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

Переходный DOCTYPE добавлен для совместимости с IE.

Ответ 10

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

YUI 2 DataTable

YUI 3 DataTable

Нажмите на примеры, чтобы увидеть прокручиваемые образцы. Поскольку я новичок в stackoverflow, я могу опубликовать только эти две ссылки.

Ответ 11

Добавить display:block; Это также удалит ненужный горизонтальный свиток в FireFox. Вы также, без сомнения, знаете, что ни один пример не работает в MSIE 8.

<table>
    <thead>
        <tr><th>This is the header and doesn't scroll</th></tr>
    </thead>
    <tbody style="height:100px; overflow:auto;display:block;">
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
    </tbody>
</table>

Ответ 12

Вот пример, который работает в IE5 +, Firefox и Chrome. Однако он использует столбцы фиксированной ширины. http://www.cssplay.co.uk/menu/tablescroll.html

Ответ 13

Если кому-то это нужно для работы в режиме IE quirks, вот как я изменил и упростил I.G. Пассивный код для работы:

.fixed_table{
       overflow: scroll;
       overflow-x: hidden;
       max-height: 300px;
       height: 300px;
       min-height: 50px;
       padding-right:0;
}
#datatable td 
{
       padding:3px;
       text-align: center;
       width: 9%;
       vertical-align: middle;
       background-color: #343435; 
       color: #E0E0E3;
       overflow:hidden;
} 
<div class="head">
    <table>
        <thead>
            <tr>
                <th>Time (GMT)</th>
                <th>Price</th>
            </tr>
        </thead>
    </table>
</div>
<div class="fixed_table">
    <table id="datatable" cellspacing="1" cellpadding="1">
        <tbody></tbody>
    </table>
</div>

Ответ 14

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

<!DOCTYPE html>
<html>
<head>
<style>
.t_heading{
  margin-top: 20px;
  font-family: Verdana, Geneva, sans-serif;
  background-color: #4CAF50;
}

.heading{
  background-color: #4CAF50;
  color: white;
  float:left;
  padding: 8px 0PX 8PX 0PX;
  border-bottom: 1px solid #ddd;
  height: 20px;
  text-align: left;
}

.t_data{
  overflow-y: scroll;
  overflow-x: hidden;
  height:0px;
  width: 100%;

}

.t_content{
    border-collapse: collapse;
    font-family: Verdana, Geneva, sans-serif;
    width: 100%;
}

.column1,.column2,.column3,.column4{
    padding: 8px 0PX 8PX 0PX;
    text-align: left;
    border-bottom: 1px solid #ddd;
}
.t_row:hover{
  background-color:#f5f5f5;
}
</style>
<script>
function setBody(){
    var body = document.body,
    html = document.documentElement;

    var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
    height = height-300;
    /*
     ** By changing the subtraction value, You can fit the table in to the screen correctly.
     ** Make sure not to come the hscroll.
     ** Or you can set fixed height with css for the div as your wish.
     */
    document.getElementById("t_data").style.height = height+"px";

    setColumnWidth("column1");
    setColumnWidth("column2");
    setColumnWidth("column3");
    setColumnWidth("column4");
}

function setColumnWidth(o){
        var object = o;
        var x = document.getElementsByClassName(object);
        var y = x[0].clientWidth;
        document.getElementById(object).style.width = y+"px";
 }
</script>
</head>

<body onload="setBody()">
<div class="t_heading">
<div class="heading"  id="column1">Heading 1</div>
<div class="heading"  id="column2">Heading 2</div>
<div class="heading"  id="column3">Heading 3</div>
<div class="heading"  id="column4">Heading 4</div>
</div>
<div class="t_data" id="t_data">
<table class="t_content">
    <tr class='t_row'>
        <td class='column1'>Column1 Row 0</td>
        <td class='column2'>Column2 Row 0</td>
        <td class='column3'>Column3 Row 0</td>
        <td class='column4'>Column4 Row 0</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 1</td>
        <td class='column2'>Column2 Row 1</td>
        <td class='column3'>Column3 Row 1</td>
        <td class='column4'>Column4 Row 1</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 2</td>
        <td class='column2'>Column2 Row 2</td>
        <td class='column3'>Column3 Row 2</td>
        <td class='column4'>Column4 Row 2</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 3</td>
        <td class='column2'>Column2 Row 3</td>
        <td class='column3'>Column3 Row 3</td>
        <td class='column4'>Column4 Row 3</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 4</td>
        <td class='column2'>Column2 Row 4</td>
        <td class='column3'>Column3 Row 4</td>
        <td class='column4'>Column4 Row 4</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 5</td>
        <td class='column2'>Column2 Row 5</td>
        <td class='column3'>Column3 Row 5</td>
        <td class='column4'>Column4 Row 5</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 6</td>
        <td class='column2'>Column2 Row 6</td>
        <td class='column3'>Column3 Row 6</td>
        <td class='column4'>Column4 Row 6</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 7</td>
        <td class='column2'>Column2 Row 7</td>
        <td class='column3'>Column3 Row 7</td>
        <td class='column4'>Column4 Row 7</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 8</td>
        <td class='column2'>Column2 Row 8</td>
        <td class='column3'>Column3 Row 8</td>
        <td class='column4'>Column4 Row 8</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 9</td>
        <td class='column2'>Column2 Row 9</td>
        <td class='column3'>Column3 Row 9</td>
        <td class='column4'>Column4 Row 9</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 10</td>
        <td class='column2'>Column2 Row 10</td>
        <td class='column3'>Column3 Row 10</td>
        <td class='column4'>Column4 Row 10</td>
    </tr>
<!--
<?php
$data = array();
for($a = 0; $a<50; $a++)
{
    $data[$a] = array();
    $data[$a][0] = "Column1 Row ".$a;
    $data[$a][1] = "Column2 Row ".$a;
    $data[$a][2] = "Column3 Row ".$a;
    $data[$a][3] = "Column4 Row ".$a;
}
/*
 ** supose you have data in an array.. which red from database. The table will draw using array data. Or you can draw the table manualy.
 ** tip: If using manual table, No need of
 ** 'var x = document.getElementsByClassName(object); var y = x[0].clientWidth;'.
 ** You can just set ID of first row cells in to some name and use it to read width.
 */
for($i=0;$i<sizeof($data);$i++){
    echo "<tr class='t_row'><td class='column1'>".$data[$i][0]."</td><td class='column2'>".$data[$i][1]."</td><td class='column3'>".$data[$i][2]."</td><td class='column4'>".$data[$i][3]."</td></tr>";
}
?>
-->
</table>
</div>
</body>
</html>