是否有跨浏览器的CSS/JavaScript技术来显示一个长HTML表,使列标题保持固定在屏幕上,而不随表体滚动。想想微软Excel中的“冻结窗格”效果。
我希望能够滚动表的内容,但总是能够在顶部看到列标题。
是否有跨浏览器的CSS/JavaScript技术来显示一个长HTML表,使列标题保持固定在屏幕上,而不随表体滚动。想想微软Excel中的“冻结窗格”效果。
我希望能够滚动表的内容,但总是能够在顶部看到列标题。
当前回答
我还创建了一个插件来解决这个问题。我的项目- jQuery。floatThead已经存在了4年多,非常成熟。
它不需要外部样式,也不期望您的表以任何特定的方式进行样式化。支持Internet Explorer9+和Firefox/Chrome浏览器。
目前(2018-05):
在GitHub上有405次提交和998个星级
这里的许多(不是全部)答案都是快速的技巧,可能解决了某个人的问题,但并不适用于每一张桌子。
其他一些插件已经很老了,可能在ie浏览器上运行得很好,但在Firefox和Chrome浏览器上就不行了。
其他回答
我开发了一个简单的轻量级jQuery插件,用于将格式良好的HTML表转换为具有固定表头和列的可滚动表。
该插件可以很好地匹配固定部分与可滚动部分的像素到像素的定位。此外,您还可以冻结水平滚动时始终显示在视图中的列数。
演示和文档: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'}
]
});
两个div,一个用于头,一个用于数据。使数据div可滚动,并使用JavaScript将标题中的列的宽度设置为与数据中的宽度相同。我认为数据列的宽度应该是固定的,而不是动态的。
以下是对马克西米利安·希尔斯(Maximilian Hils)发布的答案的改进。
这个在ie11中没有任何闪烁:
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;
}
});
我一直在寻找一个解决方案,发现大多数答案都不工作或不适合我的情况,所以我用jQuery编写了一个简单的解决方案。
这是解决方案大纲:
克隆需要固定表头的表,并放置 在原拷贝之上的克隆拷贝。 从主表上拆下表体。 从底部表中删除表头。 调整列的宽度。(我们跟踪原始列的宽度)
下面是一个可运行的演示代码。
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支持的浏览器中也能正常工作。
很多人似乎都在寻找这个答案。我发现它隐藏在这里的另一个问题的答案:同步两个不同帧的表之间的列宽度,等等
在我尝试过的几十种方法中,这是我发现的唯一一种可靠的方法,可以让你有一个滚动的底部表,头部表具有相同的宽度。
以下是我是如何做到的,首先我改进了上面的jsfiddle来创建这个函数,它在td和th上都可以工作(以防绊倒其他人谁使用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>
然后这样做:
setHeaderTableWidth('headertable1', 'basetable1');
$(window).resize(function () {
setHeaderTableWidth('headertable1', 'basetable1');
});
这是我在Stack Overflow上找到的唯一解决方案,可以解决许多类似的问题,在我所有的情况下都有效。
例如,我尝试了不与durandal工作的jQuery stickytables插件和谷歌代码项目https://code.google.com/p/js-scroll-table-header/issues/detail?id=2
其他涉及克隆表的解决方案性能很差,或者很糟糕,并不是在所有情况下都有效。
没有必要使用这些过于复杂的解决方案。只需像下面的例子一样创建两个表,并像这里描述的那样调用setHeaderTableWidth函数,然后嘣,你就完成了。
如果这对你不起作用,你可能在玩你的CSS box-sizing属性,你需要正确设置它。很容易意外地搞砸你的CSS内容。有很多事情都可能出错,所以要注意/小心。这种方法对我很有效。