带固定标题的HTML表格?

时间:2009-03-23 12:11:12

标签: javascript css html-table

是否有跨浏览器的CSS / JavaScript技术来显示长HTML表格,以使列标题保持固定在屏幕上,而不是与表格主体一起滚动。想想Microsoft Excel中的“冻结窗格”效果。

我希望能够滚动表格的内容,但始终能够看到顶部的列标题。

29 个答案:

答案 0 :(得分:172)

这可以用四行代码清晰地解决。

如果您只关心现代浏览器,使用CSS转换可以更轻松地实现固定标头。听起来很奇怪,但效果很好:

  • HTML和CSS保持原样。
  • 没有外部JavaScript依赖项。
  • 四行代码。
  • 适用于所有配置(表格布局:固定等)。
document.getElementById("wrap").addEventListener("scroll", function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});

除了Internet Explorer 8 - 。

之外,对CSS转换的支持为widely available

以下是完整的参考示例:

document.getElementById("wrap").addEventListener("scroll",function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});
/* Your existing container */
#wrap {
    overflow: auto;
    height: 400px;
}

/* CSS for demo */
td {
    background-color: green;
    width: 200px;
    height: 100px;
}
<div id="wrap">
    <table>
        <thead>
            <tr>
                <th>Foo</th>
                <th>Bar</th>
            </tr>
        </thead>
        <tbody>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
        </tbody>
    </table>
</div>

答案 1 :(得分:84)

我正在寻找一段时间的解决方案,发现大部分答案都不起作用或不适合我的情况,所以我用jQuery编写了一个简单的解决方案。

这是解决方案大纲:

  1. 克隆需要固定标头的表格,然后放置 克隆原件上的副本。
  2. 从顶部桌子上取下桌子。
  3. 从底部表格中删除表格标题。
  4. 调整列宽。 (我们跟踪原始列宽)
  5. 以下是可运行演示中的代码。

    function scrolify(tblAsJQueryObject, height) {
      var oTbl = tblAsJQueryObject;
    
      // for very large tables you can remove the four lines below
      // and wrap the table with <div> in the mark-up and assign
      // height and overflow property  
      var oTblDiv = $("<div/>");
      oTblDiv.css('height', height);
      oTblDiv.css('overflow', 'scroll');
      oTbl.wrap(oTblDiv);
    
      // save original width
      oTbl.attr("data-item-original-width", oTbl.width());
      oTbl.find('thead tr td').each(function() {
        $(this).attr("data-item-original-width", $(this).width());
      });
      oTbl.find('tbody tr:eq(0) td').each(function() {
        $(this).attr("data-item-original-width", $(this).width());
      });
    
    
      // clone the original table
      var newTbl = oTbl.clone();
    
      // remove table header from original table
      oTbl.find('thead tr').remove();
      // remove table body from new table
      newTbl.find('tbody tr').remove();
    
      oTbl.parent().parent().prepend(newTbl);
      newTbl.wrap("<div/>");
    
      // replace ORIGINAL COLUMN width				
      newTbl.width(newTbl.attr('data-item-original-width'));
      newTbl.find('thead tr td').each(function() {
        $(this).width($(this).attr("data-item-original-width"));
      });
      oTbl.width(oTbl.attr('data-item-original-width'));
      oTbl.find('tbody tr:eq(0) td').each(function() {
        $(this).width($(this).attr("data-item-original-width"));
      });
    }
    
    $(document).ready(function() {
      scrolify($('#tblNeedsScrolling'), 160); // 160 is height
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    
    <div style="width:300px;border:6px green solid;">
      <table border="1" width="100%" id="tblNeedsScrolling">
        <thead>
          <tr><th>Header 1</th><th>Header 2</th></tr>
        </thead>
        <tbody>
          <tr><td>row 1, cell 1</td><td>row 1, cell 2</td></tr>
          <tr><td>row 2, cell 1</td><td>row 2, cell 2</td></tr>
          <tr><td>row 3, cell 1</td><td>row 3, cell 2</td></tr>
          <tr><td>row 4, cell 1</td><td>row 4, cell 2</td></tr>			
          <tr><td>row 5, cell 1</td><td>row 5, cell 2</td></tr>
          <tr><td>row 6, cell 1</td><td>row 6, cell 2</td></tr>
          <tr><td>row 7, cell 1</td><td>row 7, cell 2</td></tr>
          <tr><td>row 8, cell 1</td><td>row 8, cell 2</td></tr>			
        </tbody>
      </table>
    </div>

    此解决方案适用于Chrome和IE。由于它基于jQuery,因此它也适用于其他支持jQuery的浏览器。

答案 2 :(得分:57)

我刚刚完成了一个jQuery插件,它将使用有效的HTML(必须有一个thead和tbody)获取有效的单个表,并将输出一个具有固定标题的表,可选的固定页脚,可以是克隆标题或您选择的任何内容(分页等)。如果您想利用更大的显示器,它还会在调整浏览器大小时调整表的大小。另一个附加功能是,如果表格列不能全部适合视图,则可以侧滚动。

http://fixedheadertable.com/

在github上:http://markmalek.github.com/Fixed-Header-Table/

设置非常简单,您可以为它创建自己的自定义样式。它还在所有浏览器中使用圆角。请记住,我刚刚发布它,所以它仍然是技术上的测试版,我正在熨平的问题很少。

适用于Internet Explorer 7,Internet Explorer 8,Safari,Firefox和Chrome。

答案 3 :(得分:23)

我还创建了一个解决此问题的插件。我的项目 - jQuery.floatThead现在已经存在了4年多,而且非常成熟。

它不需要外部样式,也不希望您的表格以任何特定方式设置样式。它支持Internet Explorer9 +和Firefox / Chrome。

目前(2018-05)它有:

  

GitHub上的405个提交和998个星星


这里的许多(不是全部)答案都是快速破解,可能已经解决了一个人遇到的问题,但不会对每个桌子都有效。

其他一些插件很旧,可能适用于Internet Explorer,但会在Firefox和Chrome上运行。

答案 4 :(得分:20)

TL; DR

如果你瞄准现代浏览器并且没有奢侈的样式需求:http://jsfiddle.net/dPixie/byB9d/3/ ......虽然big four version非常好,但这个版本处理流体宽度要好得多。

大家好消息!

随着HTML5和CSS3的进步,现在可以实现这一点,至少对于现代浏览器而言如此。我想出的略微讨厌的实现可以在这里找到:http://jsfiddle.net/dPixie/byB9d/3/。我在FX 25,Chrome 31和IE 10中进行了测试......

相关HTML(尽管在文档顶部插入HTML5文档类型):

<section class="positioned">
  <div class="container">
    <table>
      <thead>
        <tr class="header">
          <th>
            Table attribute name
            <div>Table attribute name</div>
          </th>
          <th>
            Value
            <div>Value</div>
          </th>
          <th>
            Description
            <div>Description</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>align</td>
          <td>left, center, right</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
        </tr>
        <tr>
          <td>bgcolor</td>
          <td>rgb(x,x,x), #xxxxxx, colorname</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
        </tr>
        <tr>
          <td>border</td>
          <td>1,""</td>
          <td>Specifies whether the table cells should have borders or not</td>
        </tr>
        <tr>
          <td>cellpadding</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
        </tr>
        <tr>
          <td>cellspacing</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between cells</td>
        </tr>
        <tr>
          <td>frame</td>
          <td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
          <td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
        </tr>
        <tr>
          <td>rules</td>
          <td>none, groups, rows, cols, all</td>
          <td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
        </tr>
        <tr>
          <td>summary</td>
          <td>text</td>
          <td>Not supported in HTML5. Specifies a summary of the content of a table</td>
        </tr>
        <tr>
          <td>width</td>
          <td>pixels, %</td>
          <td>Not supported in HTML5. Specifies the width of a table</td>
        </tr>
      </tbody>
    </table>
  </div>
</section>

使用这个CSS:

html, body{
  margin:0;
  padding:0;
  height:100%;
}
section {
  position: relative;
  border: 1px solid #000;
  padding-top: 37px;
  background: #500;
}
section.positioned {
  position: absolute;
  top:100px;
  left:100px;
  width:800px;
  box-shadow: 0 0 15px #333;
}
.container {
  overflow-y: auto;
  height: 200px;
}
table {
  border-spacing: 0;
  width:100%;
}
td + td {
  border-left:1px solid #eee;
}
td, th {
  border-bottom:1px solid #eee;
  background: #ddd;
  color: #000;
  padding: 10px 25px;
}
th {
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}
th div{
  position: absolute;
  background: transparent;
  color: #fff;
  padding: 9px 25px;
  top: 0;
  margin-left: -25px;
  line-height: normal;
  border-left: 1px solid #800;
}
th:first-child div{
  border: none;
}

但是如何?!

简单地说,你有一个表格标题,你可以通过使其高度为0px来隐藏它,它还包含用作固定标题的div。桌子的容器在顶部留下足够的空间以允许绝对定位的标题,并且带有滚动条的表格如您所期望的那样出现。

上面的代码使用定位的类来绝对定位表(我在弹出式样式对话框中使用它),但您也可以在文档流中使用它,同时删除positioned类容器。

但是......

这不完美。 Firefox拒绝将标题行设为0px(至少我没有找到任何方法)但是固执地将它保持在最低4px ......这不是一个大问题,但是根据你的造型它会弄乱你的边界等。

该表也使用了一种虚拟列方法,其中容器本身的背景颜色用作标题div的背景,这是透明的。

摘要

总而言之,可能会出现样式问题,具体取决于您的要求,尤其是边框或复杂的背景。可计算性也可能存在问题,我还没有在各种各样的浏览器中检查过它(如果你尝试的话请用你的经验评论),但我没有找到类似的东西,所以我觉得值得发帖无论如何...

答案 5 :(得分:19)

从CSS规范之外解决这个问题的所有尝试都是我们真正想要的阴影:交付THEAD的隐含承诺。

这个用于表格的冻结标题长期以来一直是HTML / CSS中的一个开放性创伤。

在一个完美的世界中,会出现一个针对此问题的纯CSS解决方案。不幸的是,似乎没有一个好的。

相关标准 - 有关该主题的讨论包括:

更新:Firefox在版本32中发布了position:sticky。每个人都赢了!

答案 6 :(得分:14)

这是一个用于固定表头的jQuery插件。它允许整个页面滚动,当标题到达顶部时冻结标题。它适用于Twitter Bootstrap表。

GitHub存储库:https://github.com/oma/table-fixed-header

仅滚动表格内容。看看其他工具,作为其他答案之一。你最好决定什么适合你的情况。

答案 7 :(得分:9)

此处发布的大多数解决方案都需要jQuery。如果您正在寻找独立于框架的解决方案,请尝试网格:http://www.matts411.com/post/grid/

它在Github上托管:https://github.com/mmurph211/Grid

它不仅支持固定标题,还支持固定的左列和页脚等。

答案 8 :(得分:6)

更精致的纯CSS滚动表

到目前为止我见过的所有纯CSS解决方案 - 虽然可能很聪明 - 缺乏一定程度的润色,或者在某些情况下不能正常工作。所以,我决定创建自己的......

特点:

  • 这是纯CSS,所以不需要jQuery(或任何JavaScript代码,为此 物质)
  • 您可以将表格宽度设置为百分比(a.k.a。“流体”)或固定值,或让内容确定其宽度(a.k.a.“auto”)
  • 列宽也可以是流动的,固定的或自动的。
  • 由于水平滚动,列永远不会与标题不对齐(在我看到的其他基于CSS的解决方案中出现的问题不需要固定宽度)。
  • 与所有流行的桌面浏览器兼容,包括Internet Explorer返回版本8
  • 清洁,抛光的外观;看上去没有看上去像素的1像素间隙或未对齐的边框;在所有浏览器中看起来都一样

以下是一些显示流体和自动宽度选项的小提琴:

  • 流体宽度和高度(适应屏幕尺寸): jsFiddle (请注意,滚动条仅在此配置中需要时显示,所以你可能需要缩小框架才能看到它)

  • 自动宽度,固定高度(更容易与其他内容集成): jsFiddle

自动宽度,固定高度配置可能有更多用例,因此我将发布以下代码。

/* The following 'html' and 'body' rule sets are required only
   if using a % width or height*/

/*html {
  width: 100%;
  height: 100%;
}*/

body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /* If you want a fixed width, set it here, else set to auto */
  min-width: 0/*100%*/; /* If you want a % width, set it here, else set to 0 */
  height: 188px/*100%*/; /* Set table height here; can be fixed value or % */
  min-height: 0/*104px*/; /* If using % height, make this large enough to fit scrollbar arrows + caption + thead */
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 16px;
  line-height: 20px;
  padding: 20px 0 20px 0; /* Need enough padding to make room for caption */
  text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /* This determines column header height */
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /* Header row background color */
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: 0/*43px*/; /* If using % height, make this large
                            enough to fit scrollbar arrows */
  max-height: 100%;
  overflow: scroll/*auto*/; /* Set to auto if using fixed
                               or % width; else scroll */
  overflow-x: hidden;
  border: 1px solid black; /* Border around table body */
}
.scrollingtable > div > div:after {background: white;} /* Match page background color */
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /* Inverse of column header height */
  /*margin-right: 17px;*/ /* Uncomment if using % width */
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /* Match column header height */
  padding-top: 1px;
  border-left: 1px solid black; /* Borders between header cells */
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /* Inverse border-width */
  background: white; /* Match page background color */
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /* Inverse of border width */
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /* Match column header height */
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /* Alternate row color */
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /* Borders between body cells */
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"/></th>
            <th><div label="Column 2"/></th>
            <th><div label="Column 3"/></th>
            <th>
              <!-- More versatile way of doing column label; requires two identical copies of label -->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!-- ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW -->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->

我用来冻结标题行的方法类似于d-Pixie的,所以请参考他的帖子进行解释。这种技术存在大量的漏洞和限制,只能通过大量额外的CSS和一个或多个div容器来修复。

答案 9 :(得分:5)

一个简单的jQuery插件

这是Mahes解决方案的变体。您可以将其称为$('table#foo').scrollableTable();

这个想法是:

  • theadtbody拆分为单独的table元素
  • 让他们的小区宽度再次匹配
  • 将第二个table换入div.scrollable
  • 使用CSS让div.scrollable实际滚动

CSS可能是:

div.scrollable { height: 300px; overflow-y: scroll;}

注意事项

  • 显然,拆分这些表会使标记语义更少。我不确定这对可访问性有什么影响。
  • 此插件不处理页脚,多个标题等。
  • 我只在Chrome版本20中测试过它。

那就是说,它适用于我的目的,你可以自由地修改它。

这是插件:

jQuery.fn.scrollableTable = function () {
  var $newTable, $oldTable, $scrollableDiv, originalWidths;
  $oldTable = $(this);

  // Once the tables are split, their cell widths may change. 
  // Grab these so we can make the two tables match again.
  originalWidths = $oldTable.find('tr:first td').map(function() {
    return $(this).width();
  });

  $newTable = $oldTable.clone();
  $oldTable.find('tbody').remove();
  $newTable.find('thead').remove();

  $.each([$oldTable, $newTable], function(index, $table) {
    $table.find('tr:first td').each(function(i) {
      $(this).width(originalWidths[i]);
    });
  });

  $scrollableDiv = $('<div/>').addClass('scrollable');
  $newTable.insertAfter($oldTable).wrap($scrollableDiv);
};

答案 10 :(得分:4)

:)

不太干净,但纯HTML / CSS解决方案。

table {
    overflow-x:scroll;
}

tbody {
    max-height: /*your desired max height*/
    overflow-y:scroll;
    display:block;
}

针对IE8 +进行了更新 JSFiddle example

答案 11 :(得分:4)

CSS属性position: sticky在大多数现代浏览器中都有很好的支持(Edge出现了问题,请参见下文)。

这使我们可以很轻松地解决固定标头的问题:

thead th { position: sticky; top: 0; }

Safari需要供应商前缀:-webkit-sticky

对于Firefox,我必须向父元素之一添加min-height: 0。我完全忘记了为什么需要这样做。

最不幸的是,Microsoft Edge实施似乎只是半工作。至少,我在测试中有一些闪烁且未对齐的表格单元。该桌子仍然可用,但存在重大美学问题。

答案 12 :(得分:3)

支持固定页脚

我扩展了Nathan的功能,以支持固定的页脚和最大高度。 此外,该函数将设置CSS本身,您只需支持宽度。

用法:

固定高度:

$('table').scrollableTable({ height: 100 });

最大高度(如果浏览器支持CSS'max-height'选项):

$('table').scrollableTable({ maxHeight: 100 });

脚本:

jQuery.fn.scrollableTable = function(options) {

    var $originalTable, $headTable, $bodyTable, $footTable, $scrollableDiv, originalWidths;

    // Prepare the separate parts of the table
    $originalTable = $(this);
    $headTable = $originalTable.clone();

    $headTable.find('tbody').remove();
    $headTable.find('tfoot').remove();

    $bodyTable = $originalTable.clone();
    $bodyTable.find('thead').remove();
    $bodyTable.find('tfoot').remove();

    $footTable = $originalTable.clone();
    $footTable.find('thead').remove();
    $footTable.find('tbody').remove();

    // Grab the original column widths and set them in the separate tables
    originalWidths = $originalTable.find('tr:first td').map(function() {
        return $(this).width();
    });

    $.each([$headTable, $bodyTable, $footTable], function(index, $table) {
        $table.find('tr:first td').each(function(i) {
            $(this).width(originalWidths[i]);
        });
    });

    // The div that makes the body table scroll
    $scrollableDiv = $('<div/>').css({
        'overflow-y': 'scroll'
    });

    if(options.height) {
        $scrollableDiv.css({'height': options.height});
    }
    else if(options.maxHeight) {
        $scrollableDiv.css({'max-height': options.maxHeight});
    }

    // Add the new separate tables and remove the original one
    $headTable.insertAfter($originalTable);
    $bodyTable.insertAfter($headTable);
    $footTable.insertAfter($bodyTable);
    $bodyTable.wrap($scrollableDiv);
    $originalTable.remove();
};

答案 13 :(得分:2)

两个div,一个用于标题,一个用于数据。使数据div可滚动,并使用JavaScript将标题中列的宽度设置为与数据中的宽度相同。我认为数据列的宽度需要固定而不是动态。

答案 14 :(得分:2)

以某种方式,我最终以Position:Sticky的情况进行了很好的工作:

table{
  width: 100%;
  border: collapse;
}

th{
    position: sticky;
    top: 0px;
    border: 1px solid black;
    background: #ff5722;
    color: #f5f5f5;
    font-weight: 600;
}
td{
    background: #d3d3d3;
    border: 1px solid black;
    color: #f5f5f5;
    font-weight: 600;
}

div{
  height: 150px
  overflow: auto;
  width: 100%
}
<div>
    <table>
        <thead>
            <tr>
                <th>header 1</th>
                <th>header 2</th>
                <th>header 3</th>
                <th>header 4</th>
                <th>header 5</th>
                <th>header 6</th>
                <th>header 7</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
        </tbody>
    </table>
</div>

答案 15 :(得分:1)

我意识到这个问题允许使用JavaScript,但这里有一个纯粹的CSS解决方案,我还可以让表格横向扩展。它已通过Internet Explorer 10和最新的Chrome和Firefox浏览器进行了测试。 jsFiddle的链接位于底部。

HTML:

Putting some text here to differentiate between the header
aligning with the top of the screen and the header aligning
with the top of one of its ancestor containers.

<div id="positioning-container">
<div id="scroll-container">
    <table>
        <colgroup>
            <col class="col1"></col>
            <col class="col2"></col>
        </colgroup>
        <thead>
            <th class="header-col1"><div>Header 1</div></th>
            <th class="header-col2"><div>Header 2</div></th>
        </thead>
        <tbody>
            <tr><td>Cell 1.1</td><td>Cell 1.2</td></tr>
            <tr><td>Cell 2.1</td><td>Cell 2.2</td></tr>
            <tr><td>Cell 3.1</td><td>Cell 3.2</td></tr>
            <tr><td>Cell 4.1</td><td>Cell 4.2</td></tr>
            <tr><td>Cell 5.1</td><td>Cell 5.2</td></tr>
            <tr><td>Cell 6.1</td><td>Cell 6.2</td></tr>
            <tr><td>Cell 7.1</td><td>Cell 7.2</td></tr>

        </tbody>
    </table>
</div>
</div>

CSS:

table{
    border-collapse: collapse;
    table-layout: fixed;
    width: 100%;
}
/* Not required, just helps with alignment for this example */
td, th{
    padding: 0;
    margin: 0;
}

tbody{
    background-color: #ddf;
}

thead {
    /* Keeps the header in place. Don't forget top: 0 */
    position: absolute;
    top: 0;
    background-color: #ddd;

    /* The 17px is to adjust for the scrollbar width.
     * This is a new css value that makes this pure
     * css example possible */
    width: calc(100% - 17px);
    height: 20px;
}

/* Positioning container. Required to position the
 * header since the header uses position:absolute
 * (otherwise it would position at the top of the screen) */
#positioning-container{
    position: relative;
}

/* A container to set the scroll-bar and
 * includes padding to move the table contents
 * down below the header (padding = header height) */
#scroll-container{
    overflow-y: auto;
    padding-top: 20px;
    height: 100px;
}
.header-col1{
    background-color: red;
}

/* Fixed-width header columns need a div to set their width */
.header-col1 div{
    width: 100px;
}

/* Expandable columns need a width set on the th tag */
.header-col2{
    width: 100%;
}
.col1 {
    width: 100px;
}
.col2{
    width: 100%;
}

http://jsfiddle.net/HNHRv/3/

答案 16 :(得分:1)

对于那些尝试过Maximilian Hils提供的解决方案并且没有成功使用Internet Explorer的人,我遇到了同样的问题(Internet Explorer 11),并发现了问题所在。

在Internet Explorer 11中,样式转换(至少使用translate)不适用于<THEAD>。我通过将样式应用于循环中的所有<TH>来解决这个问题。那很有效。我的JavaScript代码如下所示:

document.getElementById('pnlGridWrap').addEventListener("scroll", function () {
  var translate = "translate(0," + this.scrollTop + "px)";
  var myElements = this.querySelectorAll("th");
  for (var i = 0; i < myElements.length; i++) {
    myElements[i].style.transform=translate;
  }
});

在我的例子中,该表是ASP.NET中的GridView。首先我认为这是因为它没有<THEAD>,但即使我强迫它有一个,它也没有用。然后我发现了我上面写的内容。

这是一个非常好的简单解决方案。在Chrome上它是完美的,在Firefox上有点生涩,在Internet Explorer上更加生涩。但总的来说这是一个很好的解决方案。

答案 17 :(得分:0)

以下是Maximilian Hils发布的答案的改进答案。

此版本适用于Internet Explorer 11,无任何闪烁:

var headerCells = tableWrap.querySelectorAll("thead td");
for (var i = 0; i < headerCells.length; i++) {
    var headerCell = headerCells[i];
    headerCell.style.backgroundColor = "silver";
}
var lastSTop = tableWrap.scrollTop;
tableWrap.addEventListener("scroll", function () {
    var stop = this.scrollTop;
    if (stop < lastSTop) {
        // Resetting the transform for the scrolling up to hide the headers
        for (var i = 0; i < headerCells.length; i++) {
            headerCells[i].style.transitionDelay = "0s";
            headerCells[i].style.transform = "";
        }
    }
    lastSTop = stop;
    var translate = "translate(0," + stop + "px)";
    for (var i = 0; i < headerCells.length; i++) {
        headerCells[i].style.transitionDelay = "0.25s";
        headerCells[i].style.transform = translate;
    }
});

答案 18 :(得分:0)

除了@Daniel Waltrip答案。为了使用position: relative,表需要用div position:sticky括起来。所以我想在这里发布示例代码。

CSS

/* Set table width/height as you want.*/
div.freeze-header {
  position: relative;
  max-height: 150px;
  max-width: 400px;
  overflow:auto;
}

/* Use position:sticky to freeze header on top*/
div.freeze-header > table > thead > tr > th {
  position: sticky;
  top: 0;
  background-color:yellow;
}

/* below is just table style decoration.*/
div.freeze-header > table {
  border-collapse: collapse;
}

div.freeze-header > table td {
  border: 1px solid black;
}

HTML

<html>
<body>
  <div>
   other contents ...
  </div>
  <div>
   other contents ...
  </div>
  <div>
   other contents ...
  </div>

  <div class="freeze-header">
    <table>
       <thead>
         <tr>
           <th> header 1 </th>
           <th> header 2 </th>
           <th> header 3 </th>
           <th> header 4 </th>
           <th> header 5 </th>
           <th> header 6 </th>
           <th> header 7 </th>
           <th> header 8 </th>
           <th> header 9 </th>
           <th> header 10 </th>
           <th> header 11 </th>
           <th> header 12 </th>
           <th> header 13 </th>
           <th> header 14 </th>
           <th> header 15 </th>
          </tr>
       </thead>
       <tbody>
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
       </tbody>
    </table>
  </div>
</body>
</html>

演示

enter image description here

答案 19 :(得分:0)

我喜欢Maximillian Hils'回答,但我遇到了一些问题:

  1. 转换在Edge或IE中不起作用,除非您将其应用于
  2. 在Edge和IE
  3. 中滚动期间标题闪烁
  4. 我的表是使用ajax加载的,所以我想附加到窗口滚动事件而不是包装器的滚动事件
  5. 为了消除闪烁,我使用超时等待用户完成滚动,然后我应用转换 - 因此在滚动期间标题不可见。

    我也使用jQuery编写了这个,jQuery应该为你处理供应商前缀的一个优点是

        var isScrolling, lastTop, lastLeft, isLeftHidden, isTopHidden;
    
        //Scroll events don't bubble https://stackoverflow.com/a/19375645/150342
        //so can't use $(document).on("scroll", ".table-container-fixed", function (e) {
        document.addEventListener('scroll', function (event) {
            var $container = $(event.target);
            if (!$container.hasClass("table-container-fixed"))
                return;    
    
            //transform needs to be applied to th for Edge and IE
            //in this example I am also fixing the leftmost column
            var $topLeftCell = $container.find('table:first > thead > tr > th:first');
            var $headerCells = $topLeftCell.siblings();
            var $columnCells = $container
               .find('table:first > tbody > tr > td:first-child, ' +
                     'table:first > tfoot > tr > td:first-child');
    
            //hide the cells while returning otherwise they show on top of the data
            if (!isLeftHidden) {
                var currentLeft = $container.scrollLeft();
                if (currentLeft < lastLeft) {
                    //scrolling left
                    isLeftHidden = true;
                    $topLeftCell.css('visibility', 'hidden');
                    $columnCells.css('visibility', 'hidden');
                }
                lastLeft = currentLeft;
            }
    
            if (!isTopHidden) {
                var currentTop = $container.scrollTop();
                if (currentTop < lastTop) {
                    //scrolling up
                    isTopHidden = true;
                    $topLeftCell.css('visibility', 'hidden');
                    $headerCells.css('visibility', 'hidden');
                }
                lastTop = currentTop;
            }
    
            // Using timeout to delay transform until user stops scrolling
            // Clear timeout while scrolling
            window.clearTimeout(isScrolling);
    
            // Set a timeout to run after scrolling ends
            isScrolling = setTimeout(function () {
                //move the table cells. 
                var x = $container.scrollLeft();
                var y = $container.scrollTop();
    
                $topLeftCell.css('transform', 'translate(' + x + 'px, ' + y + 'px)');
                $headerCells.css('transform', 'translateY(' + y + 'px)');
                $columnCells.css('transform', 'translateX(' + x + 'px)');
    
                isTopHidden = isLeftHidden = false;
                $topLeftCell.css('visibility', 'inherit');
                $headerCells.css('visibility', 'inherit');
                $columnCells.css('visibility', 'inherit');
            }, 100);
    
        }, true);
    

    该表包含在具有类table-container-fixed的div中。

    .table-container-fixed{
        overflow: auto;
        height: 400px;
    }
    

    我将border-collapse设置为分开,否则我们会在翻译过程中丢失边框,并删除表格上的边框以阻止内容显示在滚动期间边框所在的单元格上方。

    .table-container-fixed > table {
       border-collapse: separate;
       border:none;
    }
    

    我将th背景设为白色以覆盖下面的单元格,然后添加一个与表格边框相匹配的边框 - 使用Bootstrap设置样式并滚动到视图外。

     .table-container-fixed > table > thead > tr > th {
            border-top: 1px solid #ddd !important;
            background-color: white;        
            z-index: 10;
            position: relative;/*to make z-index work*/
        }
    
                .table-container-fixed > table > thead > tr > th:first-child {
                    z-index: 20;
                }
    
    .table-container-fixed > table > tbody > tr > td:first-child,
    .table-container-fixed > table > tfoot > tr > td:first-child {
        background-color: white;        
        z-index: 10;
        position: relative;
    }
    

答案 20 :(得分:0)

<html>
<head>
    <script src="//cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
    <script>
        function stickyTableHead (tableID) {
            var $tmain = $(tableID);
            var $tScroll = $tmain.children("thead")
                .clone()
                .wrapAll('<table id="tScroll" />')
                .parent()
                .addClass($(tableID).attr("class"))
                .css("position", "fixed")
                .css("top", "0")
                .css("display", "none")
                .prependTo("#tMain");

            var pos = $tmain.offset().top + $tmain.find(">thead").height();


            $(document).scroll(function () {
                var dataScroll = $tScroll.data("scroll");
                dataScroll = dataScroll || false;
                if ($(this).scrollTop() >= pos) {
                    if (!dataScroll) {
                        $tScroll
                            .data("scroll", true)
                            .show()
                            .find("th").each(function () {
                                $(this).width($tmain.find(">thead>tr>th").eq($(this).index()).width());
                            });
                    }
                } else {
                    if (dataScroll) {
                        $tScroll
                            .data("scroll", false)
                            .hide()
                        ;
                    }
                }
            });
        }

        $(document).ready(function () {
            stickyTableHead('#tMain');
        });
    </script>
</head>

<body>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>

    <table id="tMain" >
        <thead>
        <tr>
            <th>1</th> <th>2</th><th>3</th> <th>4</th><th>5</th> <th>6</th><th>7</th> <th>8</th>

        </tr>
        </thead>
        <tbody>
            <tr><td>11111111111111111111111111111111111111111111111111111111</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
        </tbody>
    </table>
</body>
</html>

答案 21 :(得分:0)

通过将StickyTableHeaders jQuery插件应用于表格,当您向下滚动时,列标题将粘贴到视口的顶部。

示例:

&#13;
&#13;
$(function () {
    $("table").stickyTableHeaders();
});

/*! Copyright (c) 2011 by Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders
	MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */

;
(function ($, window, undefined) {
    'use strict';

    var name = 'stickyTableHeaders',
        id = 0,
        defaults = {
            fixedOffset: 0,
            leftOffset: 0,
            marginTop: 0,
            scrollableArea: window
        };

    function Plugin(el, options) {
        // To avoid scope issues, use 'base' instead of 'this'
        // to reference this class from internal events and functions.
        var base = this;

        // Access to jQuery and DOM versions of element
        base.$el = $(el);
        base.el = el;
        base.id = id++;
        base.$window = $(window);
        base.$document = $(document);

        // Listen for destroyed, call teardown
        base.$el.bind('destroyed',
        $.proxy(base.teardown, base));

        // Cache DOM refs for performance reasons
        base.$clonedHeader = null;
        base.$originalHeader = null;

        // Keep track of state
        base.isSticky = false;
        base.hasBeenSticky = false;
        base.leftOffset = null;
        base.topOffset = null;

        base.init = function () {
            base.$el.each(function () {
                var $this = $(this);

                // remove padding on <table> to fix issue #7
                $this.css('padding', 0);

                base.$originalHeader = $('thead:first', this);
                base.$clonedHeader = base.$originalHeader.clone();
                $this.trigger('clonedHeader.' + name, [base.$clonedHeader]);

                base.$clonedHeader.addClass('tableFloatingHeader');
                base.$clonedHeader.css('display', 'none');

                base.$originalHeader.addClass('tableFloatingHeaderOriginal');

                base.$originalHeader.after(base.$clonedHeader);

                base.$printStyle = $('<style type="text/css" media="print">' +
                    '.tableFloatingHeader{display:none !important;}' +
                    '.tableFloatingHeaderOriginal{position:static !important;}' +
                    '</style>');
                $('head').append(base.$printStyle);
            });

            base.setOptions(options);
            base.updateWidth();
            base.toggleHeaders();
            base.bind();
        };

        base.destroy = function () {
            base.$el.unbind('destroyed', base.teardown);
            base.teardown();
        };

        base.teardown = function () {
            if (base.isSticky) {
                base.$originalHeader.css('position', 'static');
            }
            $.removeData(base.el, 'plugin_' + name);
            base.unbind();

            base.$clonedHeader.remove();
            base.$originalHeader.removeClass('tableFloatingHeaderOriginal');
            base.$originalHeader.css('visibility', 'visible');
            base.$printStyle.remove();

            base.el = null;
            base.$el = null;
        };

        base.bind = function () {
            base.$scrollableArea.on('scroll.' + name, base.toggleHeaders);
            if (!base.isWindowScrolling) {
                base.$window.on('scroll.' + name + base.id, base.setPositionValues);
                base.$window.on('resize.' + name + base.id, base.toggleHeaders);
            }
            base.$scrollableArea.on('resize.' + name, base.toggleHeaders);
            base.$scrollableArea.on('resize.' + name, base.updateWidth);
        };

        base.unbind = function () {
            // unbind window events by specifying handle so we don't remove too much
            base.$scrollableArea.off('.' + name, base.toggleHeaders);
            if (!base.isWindowScrolling) {
                base.$window.off('.' + name + base.id, base.setPositionValues);
                base.$window.off('.' + name + base.id, base.toggleHeaders);
            }
            base.$scrollableArea.off('.' + name, base.updateWidth);
        };

        base.toggleHeaders = function () {
            if (base.$el) {
                base.$el.each(function () {
                    var $this = $(this),
                        newLeft,
                        newTopOffset = base.isWindowScrolling ? (
                        isNaN(base.options.fixedOffset) ? base.options.fixedOffset.outerHeight() : base.options.fixedOffset) : base.$scrollableArea.offset().top + (!isNaN(base.options.fixedOffset) ? base.options.fixedOffset : 0),
                        offset = $this.offset(),

                        scrollTop = base.$scrollableArea.scrollTop() + newTopOffset,
                        scrollLeft = base.$scrollableArea.scrollLeft(),

                        scrolledPastTop = base.isWindowScrolling ? scrollTop > offset.top : newTopOffset > offset.top,
                        notScrolledPastBottom = (base.isWindowScrolling ? scrollTop : 0) < (offset.top + $this.height() - base.$clonedHeader.height() - (base.isWindowScrolling ? 0 : newTopOffset));

                    if (scrolledPastTop && notScrolledPastBottom) {
                        newLeft = offset.left - scrollLeft + base.options.leftOffset;
                        base.$originalHeader.css({
                            'position': 'fixed',
                                'margin-top': base.options.marginTop,
                                'left': newLeft,
                                'z-index': 3 // #18: opacity bug
                        });
                        base.leftOffset = newLeft;
                        base.topOffset = newTopOffset;
                        base.$clonedHeader.css('display', '');
                        if (!base.isSticky) {
                            base.isSticky = true;
                            // make sure the width is correct: the user might have resized the browser while in static mode
                            base.updateWidth();
                        }
                        base.setPositionValues();
                    } else if (base.isSticky) {
                        base.$originalHeader.css('position', 'static');
                        base.$clonedHeader.css('display', 'none');
                        base.isSticky = false;
                        base.resetWidth($('td,th', base.$clonedHeader), $('td,th', base.$originalHeader));
                    }
                });
            }
        };

        base.setPositionValues = function () {
            var winScrollTop = base.$window.scrollTop(),
                winScrollLeft = base.$window.scrollLeft();
            if (!base.isSticky || winScrollTop < 0 || winScrollTop + base.$window.height() > base.$document.height() || winScrollLeft < 0 || winScrollLeft + base.$window.width() > base.$document.width()) {
                return;
            }
            base.$originalHeader.css({
                'top': base.topOffset - (base.isWindowScrolling ? 0 : winScrollTop),
                    'left': base.leftOffset - (base.isWindowScrolling ? 0 : winScrollLeft)
            });
        };

        base.updateWidth = function () {
            if (!base.isSticky) {
                return;
            }
            // Copy cell widths from clone
            if (!base.$originalHeaderCells) {
                base.$originalHeaderCells = $('th,td', base.$originalHeader);
            }
            if (!base.$clonedHeaderCells) {
                base.$clonedHeaderCells = $('th,td', base.$clonedHeader);
            }
            var cellWidths = base.getWidth(base.$clonedHeaderCells);
            base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells);

            // Copy row width from whole table
            base.$originalHeader.css('width', base.$clonedHeader.width());
        };

        base.getWidth = function ($clonedHeaders) {
            var widths = [];
            $clonedHeaders.each(function (index) {
                var width, $this = $(this);

                if ($this.css('box-sizing') === 'border-box') {
                    width = $this[0].getBoundingClientRect().width; // #39: border-box bug
                } else {
                    var $origTh = $('th', base.$originalHeader);
                    if ($origTh.css('border-collapse') === 'collapse') {
                        if (window.getComputedStyle) {
                            width = parseFloat(window.getComputedStyle(this, null).width);
                        } else {
                            // ie8 only
                            var leftPadding = parseFloat($this.css('padding-left'));
                            var rightPadding = parseFloat($this.css('padding-right'));
                            // Needs more investigation - this is assuming constant border around this cell and it's neighbours.
                            var border = parseFloat($this.css('border-width'));
                            width = $this.outerWidth() - leftPadding - rightPadding - border;
                        }
                    } else {
                        width = $this.width();
                    }
                }

                widths[index] = width;
            });
            return widths;
        };

        base.setWidth = function (widths, $clonedHeaders, $origHeaders) {
            $clonedHeaders.each(function (index) {
                var width = widths[index];
                $origHeaders.eq(index).css({
                    'min-width': width,
                        'max-width': width
                });
            });
        };

        base.resetWidth = function ($clonedHeaders, $origHeaders) {
            $clonedHeaders.each(function (index) {
                var $this = $(this);
                $origHeaders.eq(index).css({
                    'min-width': $this.css('min-width'),
                        'max-width': $this.css('max-width')
                });
            });
        };

        base.setOptions = function (options) {
            base.options = $.extend({}, defaults, options);
            base.$scrollableArea = $(base.options.scrollableArea);
            base.isWindowScrolling = base.$scrollableArea[0] === window;
        };

        base.updateOptions = function (options) {
            base.setOptions(options);
            // scrollableArea might have changed
            base.unbind();
            base.bind();
            base.updateWidth();
            base.toggleHeaders();
        };

        // Run initializer
        base.init();
    }

    // A plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[name] = function (options) {
        return this.each(function () {
            var instance = $.data(this, 'plugin_' + name);
            if (instance) {
                if (typeof options === 'string') {
                    instance[options].apply(instance);
                } else {
                    instance.updateOptions(options);
                }
            } else if (options !== 'destroy') {
                $.data(this, 'plugin_' + name, new Plugin(this, options));
            }
        });
    };

})(jQuery, window);
&#13;
body {
    margin: 0 auto;
    padding: 0 20px;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 11px;
    color: #555;
}
table {
    border: 0;
    padding: 0;
    margin: 0 0 20px 0;
    border-collapse: collapse;
}
th {
    padding: 5px;
    /* NOTE: th padding must be set explicitly in order to support IE */
    text-align: right;
    font-weight:bold;
    line-height: 2em;
    color: #FFF;
    background-color: #555;
}
tbody td {
    padding: 10px;
    line-height: 18px;
    border-top: 1px solid #E0E0E0;
}
tbody tr:nth-child(2n) {
    background-color: #F7F7F7;
}
tbody tr:hover {
    background-color: #EEEEEE;
}
td {
    text-align: right;
}
td:first-child, th:first-child {
    text-align: left;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div style="width:3000px">some really really wide content goes here</div>
<table>
    <thead>
        <tr>
            <th colspan="9">Companies listed on NASDAQ OMX Copenhagen.</th>
        </tr>
        <tr>
            <th>Full name</th>
            <th>CCY</th>
            <th>Last</th>
            <th>+/-</th>
            <th>%</th>
            <th>Bid</th>
            <th>Ask</th>
            <th>Volume</th>
            <th>Turnover</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>A.P. Møller...</td>
            <td>DKK</td>
            <td>33,220.00</td>
            <td>760</td>
            <td>2.34</td>
            <td>33,140.00</td>
            <td>33,220.00</td>
            <td>594</td>
            <td>19,791,910</td>
        </tr>
        <tr>
            <td>A.P. Møller...</td>
            <td>DKK</td>
            <td>34,620.00</td>
            <td>640</td>
            <td>1.88</td>
            <td>34,620.00</td>
            <td>34,700.00</td>
            <td>9,954</td>
            <td>346,530,246</td>
        </tr>
        <tr>
            <td>Carlsberg A</td>
            <td>DKK</td>
            <td>380</td>
            <td>0</td>
            <td>0</td>
            <td>371</td>
            <td>391.5</td>
            <td>6</td>
            <td>2,280</td>
        </tr>
        <tr>
            <td>Carlsberg B</td>
            <td>DKK</td>
            <td>364.4</td>
            <td>8.6</td>
            <td>2.42</td>
            <td>363</td>
            <td>364.4</td>
            <td>636,267</td>
            <td>228,530,601</td>
        </tr>
        <tr>
            <td>Chr. Hansen...</td>
            <td>DKK</td>
            <td>114.5</td>
            <td>-1.6</td>
            <td>-1.38</td>
            <td>114.2</td>
            <td>114.5</td>
            <td>141,822</td>
            <td>16,311,454</td>
        </tr>
        <tr>
            <td>Coloplast B</td>
            <td>DKK</td>
            <td>809.5</td>
            <td>11</td>
            <td>1.38</td>
            <td>809</td>
            <td>809.5</td>
            <td>85,840</td>
            <td>69,363,301</td>
        </tr>
        <tr>
            <td>D/S Norden</td>
            <td>DKK</td>
            <td>155</td>
            <td>-1.5</td>
            <td>-0.96</td>
            <td>155</td>
            <td>155.1</td>
            <td>51,681</td>
            <td>8,037,225</td>
        </tr>
        <tr>
            <td>Danske Bank</td>
            <td>DKK</td>
            <td>69.05</td>
            <td>2.55</td>
            <td>3.83</td>
            <td>69.05</td>
            <td>69.2</td>
            <td>1,723,719</td>
            <td>115,348,068</td>
        </tr>
        <tr>
            <td>DSV</td>
            <td>DKK</td>
            <td>105.4</td>
            <td>0.2</td>
            <td>0.19</td>
            <td>105.2</td>
            <td>105.4</td>
            <td>674,873</td>
            <td>71,575,035</td>
        </tr>
        <tr>
            <td>FLSmidth &amp; Co.</td>
            <td>DKK</td>
            <td>295.8</td>
            <td>-1.8</td>
            <td>-0.6</td>
            <td>295.1</td>
            <td>295.8</td>
            <td>341,263</td>
            <td>100,301,032</td>
        </tr>
        <tr>
            <td>G4S plc</td>
            <td>DKK</td>
            <td>22.53</td>
            <td>0.05</td>
            <td>0.22</td>
            <td>22.53</td>
            <td>22.57</td>
            <td>190,920</td>
            <td>4,338,150</td>
        </tr>
        <tr>
            <td>Jyske Bank</td>
            <td>DKK</td>
            <td>144.2</td>
            <td>1.4</td>
            <td>0.98</td>
            <td>142.8</td>
            <td>144.2</td>
            <td>78,163</td>
            <td>11,104,874</td>
        </tr>
        <tr>
            <td>Københavns ...</td>
            <td>DKK</td>
            <td>1,580.00</td>
            <td>-12</td>
            <td>-0.75</td>
            <td>1,590.00</td>
            <td>1,620.00</td>
            <td>82</td>
            <td>131,110</td>
        </tr>
        <tr>
            <td>Lundbeck</td>
            <td>DKK</td>
            <td>103.4</td>
            <td>-2.5</td>
            <td>-2.36</td>
            <td>103.4</td>
            <td>103.8</td>
            <td>157,162</td>
            <td>16,462,282</td>
        </tr>
        <tr>
            <td>Nordea Bank</td>
            <td>DKK</td>
            <td>43.22</td>
            <td>-0.06</td>
            <td>-0.14</td>
            <td>43.22</td>
            <td>43.25</td>
            <td>167,520</td>
            <td>7,310,143</td>
        </tr>
        <tr>
            <td>Novo Nordisk B</td>
            <td>DKK</td>
            <td>552.5</td>
            <td>-3.5</td>
            <td>-0.63</td>
            <td>550.5</td>
            <td>552.5</td>
            <td>843,533</td>
            <td>463,962,375</td>
        </tr>
        <tr>
            <td>Novozymes B</td>
            <td>DKK</td>
            <td>805.5</td>
            <td>5.5</td>
            <td>0.69</td>
            <td>805</td>
            <td>805.5</td>
            <td>152,188</td>
            <td>121,746,199</td>
        </tr>
        <tr>
            <td>Pandora</td>
            <td>DKK</td>
            <td>39.04</td>
            <td>0.94</td>
            <td>2.47</td>
            <td>38.8</td>
            <td>39.04</td>
            <td>350,965</td>
            <td>13,611,838</td>
        </tr>
        <tr>
            <td>Rockwool In...</td>
            <td>DKK</td>
            <td>492</td>
            <td>0</td>
            <td>0</td>
            <td>482</td>
            <td>492</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Rockwool In...</td>
            <td>DKK</td>
            <td>468</td>
            <td>12</td>
            <td>2.63</td>
            <td>465.2</td>
            <td>468</td>
            <td>9,885</td>
            <td>4,623,850</td>
        </tr>
        <tr>
            <td>Sydbank</td>
            <td>DKK</td>
            <td>95</td>
            <td>0.05</td>
            <td>0.05</td>
            <td>94.7</td>
            <td>95</td>
            <td>103,438</td>
            <td>9,802,899</td>
        </tr>
        <tr>
            <td>TDC</td>
            <td>DKK</td>
            <td>43.6</td>
            <td>0.13</td>
            <td>0.3</td>
            <td>43.5</td>
            <td>43.6</td>
            <td>845,110</td>
            <td>36,785,339</td>
        </tr>
        <tr>
            <td>Topdanmark</td>
            <td>DKK</td>
            <td>854</td>
            <td>13.5</td>
            <td>1.61</td>
            <td>854</td>
            <td>855</td>
            <td>38,679</td>
            <td>32,737,678</td>
        </tr>
        <tr>
            <td>Tryg</td>
            <td>DKK</td>
            <td>290.4</td>
            <td>0.3</td>
            <td>0.1</td>
            <td>290</td>
            <td>290.4</td>
            <td>94,587</td>
            <td>27,537,247</td>
        </tr>
        <tr>
            <td>Vestas Wind...</td>
            <td>DKK</td>
            <td>90.15</td>
            <td>-4.2</td>
            <td>-4.45</td>
            <td>90.1</td>
            <td>90.15</td>
            <td>1,317,313</td>
            <td>121,064,314</td>
        </tr>
        <tr>
            <td>William Dem...</td>
            <td>DKK</td>
            <td>417.6</td>
            <td>0.1</td>
            <td>0.02</td>
            <td>417</td>
            <td>417.6</td>
            <td>64,242</td>
            <td>26,859,554</td>
        </tr>
    </tbody>
</table>
<div style="height: 4000px">lots of content down here...</div>
&#13;
&#13;
&#13;

答案 22 :(得分:0)

我发现了这种解决方法 - 在表格上方的表格中移动标题行:

&#13;
&#13;
<html>
<head>
	<title>Fixed header</title>
	<style>
		table td {width:75px;}
	</style>
</head>

<body>
<div style="height:auto; width:350px; overflow:auto">
<table border="1">
<tr>
	<td>header 1</td>
	<td>header 2</td>
	<td>header 3</td>
</tr>
</table>
</div>

<div style="height:50px; width:350px; overflow:auto">
<table border="1">
<tr>
	<td>row 1 col 1</td>
	<td>row 1 col 2</td>
	<td>row 1 col 3</td>		
</tr>
<tr>
	<td>row 2 col 1</td>
	<td>row 2 col 2</td>
	<td>row 2 col 3</td>		
</tr>
<tr>
	<td>row 3 col 1</td>
	<td>row 3 col 2</td>
	<td>row 3 col 3</td>		
</tr>
<tr>
	<td>row 4 col 1</td>
	<td>row 4 col 2</td>
	<td>row 4 col 3</td>		
</tr>
<tr>
	<td>row 5 col 1</td>
	<td>row 5 col 2</td>
	<td>row 5 col 3</td>		
</tr>
<tr>
	<td>row 6 col 1</td>
	<td>row 6 col 2</td>
	<td>row 6 col 3</td>		
</tr>
</table>
</div>


</body>
</html>
&#13;
&#13;
&#13;

答案 23 :(得分:0)

使用最新版本的jQuery,并包含以下JavaScript代码。

$(window).scroll(function(){
  $("id of the div element").offset({top:$(window).scrollTop()});
});

答案 24 :(得分:0)

这是我们最终使用的解决方案(为了处理一些边缘情况和旧版本的Internet Explorer,我们最终也在滚动时淡出标题栏,然后在滚动结束时淡化它,但在Firefox中和WebKit浏览器这个解决方案正常工作。它假定边界崩溃:崩溃。

这个解决方案的关键是,一旦你应用 border-collapse CSS转换就可以在标题上工作,所以这只是拦截滚动事件和设置正确转换。您不需要复制任何内容。如果没有在浏览器中正确实现这种行为,很难想象一个更轻量级的解决方案。

JSFiddle:http://jsfiddle.net/podperson/tH9VU/2/

它是作为一个简单的jQuery插件实现的。你只需通过像$('thead')。sticky()这样的调用就可以让你的thead变得粘稠,它们就会徘徊。它适用于页面上的多个表格和大表格中间的头部。

$.fn.sticky = function(){
    $(this).each( function(){
        var thead = $(this),
            tbody = thead.next('tbody');

        updateHeaderPosition();

        function updateHeaderPosition(){
            if(
                thead.offset().top < $(document).scrollTop()
                && tbody.offset().top + tbody.height() > $(document).scrollTop()
            ){
                var tr = tbody.find('tr').last(),
                    y = tr.offset().top - thead.height() < $(document).scrollTop()
                        ? tr.offset().top - thead.height() - thead.offset().top
                        : $(document).scrollTop() - thead.offset().top;

                thead.find('th').css({
                    'z-index': 100,
                    'transform': 'translateY(' + y + 'px)',
                    '-webkit-transform': 'translateY(' + y + 'px)'
                });
            } else {
                thead.find('th').css({
                    'transform': 'none',
                    '-webkit-transform': 'none'
                });
            }
        }

        // See http://www.quirksmode.org/dom/events/scroll.html
        $(window).on('scroll', updateHeaderPosition);
    });
}

$('thead').sticky();

答案 25 :(得分:0)

很多人似乎都在寻找这个答案。我发现它隐藏在另一个问题的答案中: Syncing column width of between tables in two different frames, etc

在我尝试过的几十种方法中,这是我发现的唯一一种可靠的方法,可以让你有一个滚动的底部表格,表头的表格宽度相同。

我是这样做的,首先我改进了上面的jsfiddle以创建这个函数,该函数适用于tdth(如果使其他人使用{{1}用于标题行的样式。)

th

接下来,您需要创建两个表格,注意标题表应该有一个额外的var setHeaderTableWidth= function (headertableid,basetableid) { $("#"+headertableid).width($("#"+basetableid).width()); $("#"+headertableid+" tr th").each(function (i) { $(this).width($($("#"+basetableid+" tr:first td")[i]).width()); }); $("#" + headertableid + " tr td").each(function (i) { $(this).width($($("#" + basetableid + " tr:first td")[i]).width()); }); } ,以便在滚动条的顶部表格中留出空间,如下所示:

TD

然后执行以下操作:

 <table id="headertable1" class="input-cells table-striped">
        <thead>
            <tr style="background-color:darkgray;color:white;"><th>header1</th><th>header2</th><th>header3</th><th>header4</th><th>header5</th><th>header6</th><th></th></tr>
        </thead>
     </table>
    <div id="resizeToBottom" style="overflow-y:scroll;overflow-x:hidden;">
        <table id="basetable1" class="input-cells table-striped">
            <tbody >
                <tr>
                    <td>testdata</td>
                    <td>2</td>
                    <td>3</td>
                    <td>4</span></td>
                    <td>55555555555555</td>
                    <td>test</td></tr>
            </tbody>
        </table>
    </div>

这是我在Stack Overflow上找到的唯一解决方案,该解决方案可以解决许多类似的问题,这些问题在我的所有情况下都有效。

例如,我尝试了jQuery stickytables插件,该插件不适用于durandal,以及此处的Google Code项目https://code.google.com/p/js-scroll-table-header/issues/detail?id=2

其他解决方案涉及克隆表格,性能不佳,或者糟透了,并不适用于所有情况。

不需要这些过于复杂的解决方案。只需制作两个表,如下面的例子,然后调用 setHeaderTableWidth函数,就像这里描述的那样,繁荣,你就完成了

如果这对你不起作用,你可能正在玩你的CSS box-sizing属性,你需要正确设置它。很容易搞砸你的CSS内容。有很多事情可能出错,所以请注意/小心。 这种方法对我有用

答案 26 :(得分:0)

我开发了一个简单的轻量级jQuery插件,用于将格式良好的HTML表格转换为具有固定表格标题和列的可滚动表格。

该插件可以很好地匹配固定部分与可滚动部分的像素到像素的定位。此外,您还可以冻结水平滚动时始终处于视图中的列数。

演示&amp;文档: http://meetselva.github.io/fixed-table-rows-cols/

GitHub存储库: https://github.com/meetselva/fixed-table-rows-cols

以下是带有固定标题的简单表的用法

$(<table selector>).fxdHdrCol({
    width:     "100%",
    height:    200,
    colModal: [{width: 30, align: 'center'},
               {width: 70, align: 'center'}, 
               {width: 200, align: 'left'}, 
               {width: 100, align: 'center'}, 
               {width: 70, align: 'center'}, 
               {width: 250, align: 'center'}
              ]
});

答案 27 :(得分:0)

我希望我早些时候找到了@ Mark的解决方案,但在我看到这个问题之前我去写了自己的解决方案...

Mine是一个非常轻量级的jQuery插件,支持固定页眉,页脚,列跨越(colspan),调整大小,水平滚动以及在滚动开始之前显示的可选行数。

jQuery.scrollTableBody (GitHub)

只要您的表格包含正确的<thead><tbody>和(可选)<tfoot>,您只需要这样做:

$('table').scrollTableBody();

答案 28 :(得分:0)

这不是固定标题行的精确解决方案,但是我创建了一种相当巧妙的方法,可以在整个长表中重复标题行,但仍保留排序功能。

这个简洁的小选项需要jQuery tablesorter plugin。以下是它的工作原理:

<强> HTML

<table class="tablesorter boxlist" id="pmtable">
    <thead class="fixedheader">
        <tr class="boxheadrow">
            <th width="70px" class="header">Job Number</th>
            <th width="10px" class="header">Pri</th>
            <th width="70px" class="header">CLLI</th>
            <th width="35px" class="header">Market</th>
            <th width="35px" class="header">Job Status</th>
            <th width="65px" class="header">Technology</th>
            <th width="95px;" class="header headerSortDown">MEI</th>
            <th width="95px" class="header">TEO Writer</th>
            <th width="75px" class="header">Quote Due</th>
            <th width="100px" class="header">Engineer</th>
            <th width="75px" class="header">ML Due</th>
            <th width="75px" class="header">ML Complete</th>
            <th width="75px" class="header">SPEC Due</th>
            <th width="75px" class="header">SPEC Complete</th>
            <th width="100px" class="header">Install Supervisor</th>
            <th width="75px" class="header">MasTec OJD</th>
            <th width="75px" class="header">Install Start</th>
            <th width="30px" class="header">Install Hours</th>
            <th width="75px" class="header">Revised CRCD</th>
            <th width="75px" class="header">Latest Ship-To-Site</th>
            <th width="30px" class="header">Total Parts</th>
            <th width="30px" class="header">OEM Rcvd</th>
            <th width="30px" class="header">Minor Rcvd</th>
            <th width="30px" class="header">Total Received</th>
            <th width="30px" class="header">% On Site</th>
            <th width="60px" class="header">Actions</th>
        </tr>
    </thead>
        <tbody class="scrollable">
            <tr data-job_id="3548" data-ml_id="" class="odd">
                <td class="c black">FL-8-RG9UP</td>
                <td data-pri="2" class="priority c yellow">M</td>
                <td class="c">FTLDFLOV</td>
                <td class="c">SFL</td>
                <td class="c">NOI</td>
                <td class="c">TRANSPORT</td>
                <td class="c"></td>
                <td class="c">Chris Byrd</td>
                <td class="c">Apr 13, 2013</td>
                <td class="c">Kris Hall</td>
                <td class="c">May 20, 2013</td>
                <td class="c">May 20, 2013</td>
                <td class="c">Jun 5, 2013</td>
                <td class="c">Jun 7, 2013</td>
                <td class="c">Joseph Fitz</td>
                <td class="c">Jun 10, 2013</td>
                <td class="c">TBD</td>
                <td class="c">123</td>
                <td class="c revised_crcd"><input readonly="true" name="revised_crcd" value="Jul 26, 2013" type="text" size="12" class="smInput r_crcd c hasDatepicker" id="dp1377194058616"></td>
                <td class="c">TBD</td>
                <td class="c">N/A</td>
                <td class="c">N/A</td>
                <td class="c">N/A</td>
                <td class="c">N/A</td>
                <td class="c">N/A</td>
                <td class="actions"><span style="float:left;" class="ui-icon ui-icon-folder-open editJob" title="View this job" s="" details'=""></span></td>
            </tr>
            <tr data-job_id="4264" data-ml_id="2959" class="even">
                <td class="c black">MTS13009SF</td>
                <td data-pri="2" class="priority c yellow">M</td>
                <td class="c">OJUSFLTL</td>
                <td class="c">SFL</td>
                <td class="c">NOI</td>
                <td class="c">TRANSPORT</td>
                <td class="c"></td>
                <td class="c">DeMarcus Stewart</td>
                <td class="c">May 22, 2013</td>
                <td class="c">Ryan Alsobrook</td>
                <td class="c">Jun 19, 2013</td>
                <td class="c">Jun 27, 2013</td>
                <td class="c">Jun 19, 2013</td>
                <td class="c">Jul 4, 2013</td>
                <td class="c">Randy Williams</td>
                <td class="c">Jun 21, 2013</td>
                <td class="c">TBD</td>
                <td class="c">95</td>
                <td class="c revised_crcd"><input readonly="true" name="revised_crcd" value="Aug 9, 2013" type="text" size="12" class="smInput r_crcd c hasDatepicker" id="dp1377194058632"></td><td class="c">TBD</td>
                <td class="c">0</td>
                <td class="c">0.00%</td>
                <td class="c">0.00%</td>
                <td class="c">0.00%</td>
                <td class="c">0.00%</td>
                <td class="actions"><span style="float:left;" class="ui-icon ui-icon-folder-open editJob" title="View this job" s="" details'=""></span><input style="float:left;" type="hidden" name="req_ship" class="reqShip hasDatepicker" id="dp1377194058464"><span style="float:left;" class="ui-icon ui-icon-calendar requestShip" title="Schedule this job for shipping"></span><span class="ui-icon ui-icon-info viewOrderInfo" style="float:left;" title="Show material details for this order"></span></td>
            </tr>
            .
            .
            .
            .
            <tr class="boxheadrow repeated-header">
                <th width="70px" class="header">Job Number</th>
                <th width="10px" class="header">Pri</th>
                <th width="70px" class="header">CLLI</th>
                <th width="35px" class="header">Market</th>
                <th width="35px" class="header">Job Status</th>
                <th width="65px" class="header">Technology</th>
                <th width="95px;" class="header">MEI</th>
                <th width="95px" class="header">TEO Writer</th>
                <th width="75px" class="header">Quote Due</th>
                <th width="100px" class="header">Engineer</th>
                <th width="75px" class="header">ML Due</th>
                <th width="75px" class="header">ML Complete</th>
                <th width="75px" class="header">SPEC Due</th>
                <th width="75px" class="header">SPEC Complete</th>
                <th width="100px" class="header">Install Supervisor</th>
                <th width="75px" class="header">MasTec OJD</th>
                <th width="75px" class="header">Install Start</th>
                <th width="30px" class="header">Install Hours</th>
                <th width="75px" class="header">Revised CRCD</th>
                <th width="75px" class="header">Latest Ship-To-Site</th>
                <th width="30px" class="header">Total Parts</th>
                <th width="30px" class="header">OEM Rcvd</th>
                <th width="30px" class="header">Minor Rcvd</th>
                <th width="30px" class="header">Total Received</th>
                <th width="30px" class="header">% On Site</th>
                <th width="60px" class="header">Actions</th>
            </tr>

显然,我的表有比这更多的行。确切地说,但是你可以看到标题行重复的位置。重复标题行由此函数设置:

<强>的jQuery

// Clone the original header row and add the "repeated-header" class
var tblHeader = $('tr.boxheadrow').clone().addClass('repeated-header');

// Add the cloned header with the new class every 34th row (or as you see fit)
$('tbody tr:odd:nth-of-type(17n)').after(tblHeader);

// On the 'sortStart' routine, remove all the inserted header rows
$('#pmtable').bind('sortStart', function() {
    $('.repeated-header').remove();
    // On the 'sortEnd' routine, add back all the header row lines.
}).bind('sortEnd', function() {
    $('tbody tr:odd:nth-of-type(17n)').after(tblHeader);
});