Html 可滚动div内的冻结表标题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/486576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 23:07:14  来源:igfitidea点击:

Frozen table header inside scrollable div

htmlasp.netscrollhtml-table

提问by rafek

I've three divs. Header, central and footer. There is a table in central div (gridview) which is almost always longer than outer div. So I've made this div scrollable vertically. The question is: how can I make table header that it would be visible after div is scrolled down? I could have done this header with separate div or table and make it fixed but widths of columns in the table are not always the same - so I don't know how to maintain widths of columns in header then. Any clue?

我有三个 div。页眉、中央和页脚。中央 div (gridview) 中有一个表格,它几乎总是比外部 div 长。所以我让这个 div 可以垂直滚动。问题是:如何使表格标题在向下滚动 div 后可见?我可以用单独的 div 或 table 完成这个标题并使其固定,但表格中的列宽并不总是相同 - 所以我不知道如何保持标题中的列宽。有什么线索吗?

回答by Mark

I've just put together a jQuery plugin that does exactly what you want. Its very small in size and really easy to implement.

我刚刚组装了一个 jQuery 插件,它完全可以满足您的需求。它的尺寸非常小,非常容易实现。

All that is required is a table that has a thead and tbody.

所需要的只是一个具有thead 和tbody 的表。

You can wrap that table in a DIV with a classname and the table will always resize to fit in that div. so for example if your div scales with the browser window so will the table. The header will be fixed when scrolling. The footer will be fixed (if you enable a footer). You also have the option to clone the header in the footer and have it fixed. Also if you make your browser window too small and all columns can't fit...it will also scroll horizontally (header too).

您可以使用类名将该表包装在 DIV 中,并且该表将始终调整大小以适合该 div。例如,如果您的 div 与浏览器窗口一起缩放,那么表格也会缩放。滚动时标题将被固定。页脚将被修复(如果您启用页脚)。您还可以选择在页脚中克隆页眉并修复它。此外,如果您将浏览器窗口设置得太小并且所有列都无法容纳……它也会水平滚动(标题也是如此)。

you just pass the DIV's classname to the plugin like so: $('.myDiv').fixedHeaderTable({footer: true, footerId: 'myFooterId'}); and the plugin will do the rest. FooterID is a element on the page that contains the mark-up for your footer. this is used if you want to have pagination as your footer.

您只需将 DIV 的类名传递给插件,如下所示: $('.myDiv').fixedHeaderTable({footer: true, footerId: 'myFooterId'}); 插件将完成剩下的工作。FooterID 是页面上包含页脚标记的元素。如果您想将分页作为页脚,则使用此选项。

If you have multiple tables on the page it will also work for each table you want to have a fixed header.

如果页面上有多个表格,它也适用于您想要固定标题的每个表格。

check it out here: http://fixedheadertable.mmalek.com/

在这里查看:http: //fixedheadertable.mmalek.com/

Keep in mind its still 'beta' so I am adding new features and bug fixes daily.

请记住它仍然是“测试版”,所以我每天都会添加新功能和错误修复。

Supported browsers: IE6, IE7, IE8, FireFox, Safari, and Chrome

支持的浏览器:IE6、IE7、IE8、FireFox、Safari 和 Chrome

回答by Borut D.

Solution is really simple. You need 3 DIVs: a general container (in my case of class "outer"), a table container (in my case of class "inner") and a DIV in which you make a clone of an existing table using jQuery or javaScript (in my case of class "header").

解决方法真的很简单。您需要 3 个 DIV:一个通用容器(在我的类“外部”的情况下)、一个表容器(在我的类“内部”的情况下)和一个 DIV,您可以在其中使用 jQuery 或 javaScript(在我的类“标题”的情况下)。

Solution uses CSS and a few lines of jQuery code, which clones HTML of "inner" into "header" and sets its width and height. Supports fixed and variable columns width. Tested with IE8, Firefox 9, Safari and Google Chrome.

解决方案使用CSS和几行jQuery代码,将“inner”的HTML克隆到“header”并设置其宽度和高度。支持固定和可变列宽。使用 IE8、Firefox 9、Safari 和 Google Chrome 进行测试。

Here is a sample code:

这是一个示例代码:

     $(document).ready(function() {
      $('.header').html( $('.inner').html() );
      $('.header').css('width', $('.inner table').outerWidth() );
      $('.header').css('height', $('.inner table thead').outerHeight() );
     });
table {
  width:100%;
}
th {
  border-top:1px solid #999;
  text-align:left;
}
td, th {
  border-bottom:1px solid #999;
  background-color:#EEE;
}
.outer {
  position:relative;
  width:500px;
}
.inner {
  height:150px;
  overflow:auto;
}
.header {
  position:absolute;
  top:0;
  left:0;
  overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="outer">
  <div class="inner">
    <table cellspacing="0" cellpadding="0">
      <thead>
        <tr>
          <th>a</th>
          <th>b</th>
          <th>c</th>
          <th>d</th>
        </tr>
      </thead>
      <tbody>
        <tr><td>1</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>2</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>3</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>4</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>5</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>6</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>7</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>8</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>9</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>10</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>11</td><td>b</td><td>c</td><td>d</td></tr>
        <tr><td>12</td><td>b</td><td>c</td><td>d</td></tr>
      </tbody>
    </table>
  </div>

  <div class="header">
  </div>

</div>
</body>

回答by alumb

Here is a basic solution using javascript:

这是使用javascript的基本解决方案:

function position(table) {
    table.rows[0].style.position="absolute";
    table.rows[0].style.top="0px";
    table.style.marginTop = table.rows[0].clientHeight/1.2;
    var widths = Array();
    for(var i = 0; i < table.rows[0].cells.length; i++) {
        widths[i] = max(table.rows[0].cells[i].clientWidth, table.rows[1].cells[i].clientWidth);
    }
    for(var row = 0; row < table.rows.length; row++) {
        for(var col = 0; col < widths.length; col ++) {
            table.rows[row].cells[col].style.width = widths[col] + "px";
        }
    }
}

function max(num1, num2) { return (num1 > num2) ? num1 : num2; }

回答by Draemon

You would have to put the header outside the scrollable div. Everything within the div will scroll.

您必须将标题放在可滚动 div 之外。div 中的所有内容都会滚动。

EDIT

编辑

Regarding the width if you go for a separate header, I can see a few solutions:

如果您选择单独的标题,关于宽度,我可以看到一些解决方案:

  • Assuming this is dynamic content, generate "fixed" widths based on the length of the string. Obviously specify in terms of EMs and leave some margin for error.
  • Use javascript.
  • Use fixed width columns.
  • 假设这是动态内容,则根据字符串的长度生成“固定”宽度。显然以 EM 的形式指定,并留出一些误差余量。
  • 使用 JavaScript。
  • 使用固定宽度的列。

I haven't actually tried the first, and it might be overcomplicating things a bit. It's something to try if you're desperate for the effect though.

我实际上还没有尝试过第一个,这可能会使事情变得过于复杂。不过,如果您非常渴望效果,可以尝试一下。

I should also mention that there are probably javascript libraries with table widgets that do this already. Have a look at them to see how they do it.

我还应该提到,可能已经有带有表格小部件的 javascript 库可以做到这一点。看看他们,看看他们是如何做到的。

回答by Greg

You need to put a table with the headers about your table of data. You can maintain the column width with table-layout:fixed. JavaScript can be used to match the column widths.

您需要放置一个表,其中包含有关数据表的标题。您可以使用 table-layout:fixed 保持列宽。JavaScript 可用于匹配列宽。

回答by waqas

Here's a nice solution (mostly CSS) which uses fixed width columns: http://www.imaputz.com/cssStuff/bulletVersion.html

这是一个使用固定宽度列的不错的解决方案(主要是 CSS):http: //www.imaputz.com/cssStuff/bulletVersion.html

And here's a bit of jQuery code to fix cell-widths when cell contents take more width than the fixed width:

当单元格内容的宽度大于固定宽度时,这里有一些 jQuery 代码来修复单元格宽度:

<script
  src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"
  type="text/javascript"></script>
<script>
$(function() {
  $('div.tableContainer').each(function() { // for each table
    var div = $(this);
    var widths = [];
    var changed = false;
    $('table>*>tr', div).each(function(tr_i) {
      $(this).children().each(function(i) {
        var w = $(this).width();
        if (w > widths[i]) {
            widths[i] = w;
            changed = true;
        }
      });
    }).each(function(tr_i) {
      if (changed)
      $(this).children().each(function(i) {
        var width = widths[i];
        // add some width for scrollbar
        if (tr_i == 0 && changed && i == widths.length-1) width += 16;
        // insert a div to ensure width
        $(this).append('<div style="width:'+width+'px; height:0px">&nbsp;</div>');
      });
    });
    div.width(div.children('table').width()).css('overflow-x', 'hidden');
  });
});
</script>

The output is a bit off in IE when using a non-strict DTD. Tweak the widths in the CSS if you can't use standards mode.

使用非严格 DTD 时,IE 中的输出有点偏离。如果您不能使用标准模式,请调整 CSS 中的宽度。

Note that the jQuery code increases the table width at the end, and disables the horizontal scrollbar. You may or may not want that.

请注意,jQuery 代码在最后增加了表格宽度,并禁用了水平滚动条。你可能想要也可能不想要。

回答by Hymanysee

You may try the jQuery plugin Stupid Fixed Header. The technique is basically the same: clone a header and put it on top of the table layer.

你可以试试 jQuery 插件Stupid Fixed Header。技术基本相同:克隆一个标题并将其放在表层的顶部。

回答by annakata

What you actually want to be doing is making the <tbody>of the data table scrollable, so the <thead>and <tfoot>will remain naturally fixed.

您真正想要做的是使<tbody>数据表的 可滚动,因此<thead><tfoot>将保持自然固定。

Whilst this is trivial for FF et al:

虽然这对 FF 等人来说是微不足道的:

tbody
{
    height: 100px; /* or whatever */
    overflow: auto;
    overflow-y: auto;
    overflow-x: hidden;
}

IE has severeand complex issues with tbody in general. It can be solved with expressions but it's non-trivial, and specific to the design.

一般而言,IE与 tbody存在严重而复杂的问题。它可以用表达式解决,但它很重要,并且特定于设计。

回答by Chui Tey

Take a look at YUI Data Table if you are looking for a comprehensive cross-browser implementation. I believe this is done by creating another table with matching column widths.

如果您正在寻找全面的跨浏览器实现,请查看 YUI 数据表。我相信这是通过创建另一个具有匹配列宽的表格来完成的。

There appears to be tricks required to fix column widths. If I recall correctly, Firefox requires <col/> tags to be present.

似乎需要一些技巧来修复列宽。如果我没记错的话,Firefox 需要 <col/> 标签。

In any case, there were many tricks employed in YUI DataTable (50k lines). You'd be well advised to look at it and decide how far you'd like to go on your own with this.

无论如何,在 YUI DataTable(50k 行)中使用了许多技巧。建议您查看它并决定您想自己走多远。

回答by Andrew Duffy

This solution works using CSS in Firefox and the other Gecko browsers, and CSS expressions in IE.

该解决方案在 Firefox 和其他 Gecko 浏览器中使用 CSS,在 IE 中使用 CSS 表达式。

http://home.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html

http://home.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html

The header and footer do not stay fixed in Opera or Safari/Chrome, but the whole table is scrollable so it is usable. Note that the columns are given percentage widths in the author's example, but they can be removed.

页眉和页脚在 Opera 或 Safari/Chrome 中不会保持固定,但整个表格是可滚动的,因此它是可用的。请注意,在作者的示例中,列被赋予了百分比宽度,但它们可以被删除。

If you want to experiment with Opera/Safari/Chrome support, look at giving the tbody display:block and go from there.

如果你想尝试 Opera/Safari/Chrome 支持,看看给 tbody display:block 并从那里开始。