代码之家  ›  专栏  ›  技术社区  ›  Andrew Ensley

使tBody在WebKit浏览器中可滚动

  •  68
  • Andrew Ensley  · 技术社区  · 15 年前

    我知道 this question 但这些答案都不适用于Safari、Chrome等。

    公认的战略( as demonstrated here )设置tbody height和overflow属性,如下所示:

    <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浏览器中都不起作用。有一个 bug report 关于它,这似乎不是一个高优先级(6月5日报道)。

    所以我的问题是:是否有其他的策略确实有效?我已经尝试过使用双表方法,但是不可能保证标题与内容一致。我需要等待WebKit来修复它吗?

    14 回复  |  直到 8 年前
        1
  •  32
  •   Michael Koper    13 年前

    下面是一个工作示例:

    http://www.imaputz.com/cssStuff/bigFourVersion.html

    您必须将显示块添加到ad>tr和tbody

        2
  •  17
  •   Martin    15 年前

    只有在有1列的情况下,才能使用display:block样式。如果您有多个数据列(包含多个字段),那么display:block将使所有数据列都可滚动,但在第一列下(在firefox中也是如此,我只知道firefox是唯一一个可以很好滚动的浏览器)。顺便说一下,在火狐上,你可以使用overflow-x:hidden样式来抑制水平滚动。

    我意识到,我提到的问题只有在您没有为th&td元素指定宽度的情况下才会发生-如果您可以修复列宽,那么它就会起作用。对我来说,问题是我不能固定列宽。

        3
  •  12
  •   lsf    13 年前

    尝试此页的第一种方法,纯CSS和一张表(表周围有两个div,thead为绝对位置): http://www.cssplay.co.uk/menu/tablescroll.html 除了IE7/FF3.6外,似乎还适用于FF4/IE9/IE8。

        4
  •  5
  •   Sean Haddy    12 年前

    我有同样的问题,写了一个jquery脚本来为我做这件事…使用两个表元素并相应地格式化CSS。希望这能帮助其他有同样问题的人…

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

        5
  •  5
  •   Community CDub    7 年前

    我看到肖恩·哈迪的 excellent solution 自由地 making some edits :

    • 使用类而不是ID,因此可以重用一个jquery脚本 一页上有多个表
    • 添加了对语义HTML表元素(如标题、thead、tfoot和tbody)的支持
    • 使滚动条成为可选的,这样它就不会出现在“短于”可滚动高度的表中。
    • 调整滚动DIV的宽度,使滚动条上升到表的右边缘
    • 使概念容易被
      • 在注入的静态表头上使用aria hidden=“true”
      • 将原来的thead保留在适当的位置,只需使用jquery隐藏并设置 aria-hidden="false"
    • 显示了不同大小的多个表的示例

    不过,肖恩做了一次举重。也要感谢马特·伯兰,他指出需要支持特富特。

    请自己看一下 http://jsfiddle.net/jhfrench/eNP2N/

        6
  •  3
  •   I.G. Pascual    13 年前

    A很久以前就面临着同样的问题,我终于提出了两表法。结果是: http://jsfiddle.net/bGr4V/3/ ,适用于所有浏览器(包括IE6+浏览器)。

    this jsFiddle 你可以玩干净的版本。

    我的解决方案是添加 固定单元 <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
  •  2
  •   TJ VanToll    12 年前

    我想我会把我的溶液加入混合物- http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/ .

    它采用与@michael koper的解决方案相同的基本路线,但包含一个变通方案,以便在IE返回IE6时表看起来正确。

    我通过给出 <table> table-layout: fixed 并显式地为每列中的单元格指定宽度。不理想,但它确实生成了一个语义表,不管是否需要滚动条,该表都将跨浏览器对齐。

    演示: http://codepen.io/tjvantoll/pen/JEKIu

        8
  •  1
  •   Stephen Gerard Darragh    13 年前

    我为上述问题开发了JavaScript解决方案
    它只在Firefox 7+中工作,因为我只在FF中测试过。

    我走到这条线前,发现了 米迦勒科佩尔

    在这个解决方案中,有三件重要的事情要做
    1)固定列宽
    2)将AD>TR显示设置为“阻止”
    3)t车身显示屏设置为BLOCK(阻止)。

    正如其他人提到的那样,有一个固定宽度的问题,我也处于同样的位置;
    即使我不能静态固定宽度

    所以我想我会动态地调整宽度(在浏览器中呈现表之后) 这就成功了:)

    下面是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";  
            }
    

    此解决方案从浏览器中找出列的宽度
    再次将相同的宽度设置为列(标题和正文的第一行)
    设置宽度后,将“D>TR”和“T车身显示”设置为“阻止”

    希望这个解决方案对你们大家都有用。
    如果您可以将其扩展到其他浏览器,请回复此帖子

        9
  •  1
  •   Matthew    13 年前

    这真的很烂,但是 也许吧 它会在某个地方帮助某人…

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

    它使用列而不是行,因此处理基本上是向后进行的。

    为IE兼容性添加了过渡doctype。

        10
  •  1
  •   Tim Penner    8 年前

    对于这个问题来说,这可能是多余的,但是Yui仍然提供了可能最好的免费跨浏览器数据表。它也可以用于只读数据。

    YUI 2 DataTable

    YUI 3 DataTable

    单击此处的示例以查看可滚动的示例。因为我是StackOverflow的新手,所以我只能发布这两个链接。

        11
  •  0
  •   mmcglynn    15 年前

    添加 display:block; 这也将删除Firefox中不必要的水平滚动。毫无疑问,您也知道这两个示例在MSIE8中都不起作用。

    <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
  •  0
  •   user1491819    10 年前

    这里有一个例子可以在IE5+、火狐和Chrome中使用。但是,它使用固定宽度的列。 http://www.cssplay.co.uk/menu/tablescroll.html

        13
  •  0
  •   ronenfe    9 年前

    如果有人需要它在ie-quirks模式下工作,下面是我如何更改和简化i.g.pascual的代码:

    .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
  •  0
  •   Salitha Prasad    8 年前

    让表格按其方式绘制,计算每列的宽度,并将其设置为每个标题。标题是用分隔符制作的,然后我们可以让表格自由滚动。

    <!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's 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>