Che*_*oft 227 javascript css html-table
是否有跨浏览器的CSS/JavaScript技术来显示长HTML表格,使列标题保持固定在屏幕上,不要与表格主体一起滚动.想想Microsoft Excel中的"冻结窗格"效果.
我希望能够滚动表格的内容,但始终能够看到顶部的列标题.
Max*_*ils 177
如果您只关心现代浏览器,那么使用CSS转换可以更轻松地实现固定标头.听起来很奇怪,但效果很好:
document.getElementById("wrap").addEventListener("scroll", function(){
var translate = "translate(0,"+this.scrollTop+"px)";
this.querySelector("thead").style.transform = translate;
});
Run Code Online (Sandbox Code Playgroud)
除Internet Explorer 8外,广泛支持CSS转换.
以下是完整的参考示例:
document.getElementById("wrap").addEventListener("scroll",function(){
var translate = "translate(0,"+this.scrollTop+"px)";
this.querySelector("thead").style.transform = translate;
});
Run Code Online (Sandbox Code Playgroud)
/* Your existing container */
#wrap {
overflow: auto;
height: 400px;
}
/* CSS for demo */
td {
background-color: green;
width: 200px;
height: 100px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
Mah*_*hes 87
我一直在寻找一个解决方案,发现大多数答案都不起作用或不适合我的情况,所以我用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
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
此解决方案适用于Chrome和IE.由于它基于jQuery,因此它也适用于其他支持jQuery的浏览器.
Mar*_*ark 57
我刚刚完成了一个jQuery插件,它将使用有效的HTML(必须有一个thead和tbody)获取有效的单个表,并将输出一个具有固定标题的表,可选的固定页脚,可以是克隆的标题或任何你选择的内容(分页等).如果您想利用更大的显示器,它还会在调整浏览器大小时调整表的大小.另一个附加功能是,如果表格列不能全部适合视图,则可以侧滚动.
在github上:http://markmalek.github.com/Fixed-Header-Table/
它非常容易设置,您可以为它创建自己的自定义样式.它还在所有浏览器中使用圆角.请记住,我刚刚发布它,所以它仍然是技术上的测试版,我正在熨平的问题很少.
它适用于Internet Explorer 7,Internet Explorer 8,Safari,Firefox和Chrome.
mko*_*yak 23
我还创建了一个解决此问题的插件.我的项目--jQuery.floatThead已经存在了4年多,而且非常成熟.
它不需要外部样式,也不希望您的表格以任何特定方式设置样式.它支持Internet Explorer9 +和Firefox/Chrome.
目前(2018-05)它有:
GitHub上有405个提交和998个星
这里的许多(不是全部)答案都是快速的黑客攻击,可能已经解决了一个人遇到的问题,但不会对每张桌子都有效.
其他一些插件很旧,可能适用于Internet Explorer,但会在Firefox和Chrome上运行.
Jon*_*son 20
如果您瞄准现代浏览器并且没有奢侈的样式需求:http://jsfiddle.net/dPixie/byB9d/3/ ...虽然四大版本非常好,但这个版本处理流体宽度要好得多.
随着HTML5和CSS3的进步,现在这是可能的,至少对于现代浏览器而言.我想出的稍微讨厌的实现可以在这里找到:http://jsfiddle.net/dPixie/byB9d/3/.我在FX 25,Chrome 31和IE 10中进行了测试......
相关HTML(尽管在文档顶部插入HTML5文档类型):
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;
}
Run Code Online (Sandbox Code Playgroud)
有了这个CSS:
<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>
Run Code Online (Sandbox Code Playgroud)
简单地说,你有一个表头,你可以通过使其高度为0px来隐藏它,它还包含用作固定头的div.桌子的容器在顶部留出足够的空间以允许绝对定位的标题,并且带有滚动条的表格如您所期望的那样出现.
上面的代码使用定位的类来绝对定位表(我在弹出样式对话框中使用它),但是您可以在文档流中使用它,也可以positioned
从容器中删除类.
这不完美.Firefox拒绝将标题行设为0px(至少我没有找到任何方法)但是固执地将它保持在最低4px ...这不是一个大问题,但根据你的造型它会弄乱你的边界等.
该表还使用了一种虚拟列方法,其中容器本身的背景颜色用作标题div的背景,这是透明的.
总而言之,根据您的要求,可能存在造型问题,尤其是边框或复杂背景.可计算性也可能存在问题,我还没有在各种各样的浏览器中检查过它(如果你尝试的话请用你的经验评论),但我没有找到类似的东西,所以我觉得值得发帖无论如何......
djs*_*off 19
从CSS规范之外解决这个问题的所有尝试都是我们真正想要的阴影:交付THEAD的隐含承诺.
这个用于表格的冻结标题长期以来一直是HTML/CSS中的一个开放性创伤.
在一个完美的世界中,会有一个纯CSS解决方案来解决这个问题.不幸的是,似乎没有一个好的.
相关标准 - 关于该主题的讨论包括:
更新:Firefox position:sticky
在版本32中发布.每个人都赢了!
oma*_*oma 14
这是一个用于固定表头的jQuery插件.它允许整个页面滚动,当标题到达顶部时冻结标题.它适用于Twitter Bootstrap表.
GitHub存储库:https://github.com/oma/table-fixed-header
它并没有滚动只表的内容.看看其他工具,作为其他答案之一.你决定什么最适合你的情况.
小智 9
这里发布的大多数解决方案都需要jQuery.如果您正在寻找独立于框架的解决方案,请尝试使用Grid:http://www.matts411.com/post/grid/
它在Github上托管:https://github.com/mmurph211/Grid
它不仅支持固定标题,还支持固定的左列和页脚等.
到目前为止我见过的所有纯CSS解决方案 - 虽然可能很聪明 - 缺乏一定程度的润色,或者在某些情况下不能正常工作.所以,我决定创建自己的......
特征:
以下是一些显示流体和自动宽度选项的小提琴:
自动宽度,固定高度配置可能有更多的用例,所以我将发布下面的代码.
/* 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;
color: black;
}
.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 */
Run Code Online (Sandbox Code Playgroud)
<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]-->
Run Code Online (Sandbox Code Playgroud)
我用来冻结标题行的方法类似于d-Pixie的,所以请参考他的帖子进行解释.这种技术存在大量的漏洞和限制,只能通过大量额外的CSS和一个或多个div容器来修复.
CSS属性position: sticky
在大多数现代浏览器中都有很好的支持(Edge出现了问题,请参见下文)。
这使我们可以很轻松地解决固定标头的问题:
thead th { position: sticky; top: 0; }
Run Code Online (Sandbox Code Playgroud)
Safari需要供应商前缀:-webkit-sticky
。
对于Firefox,我必须将min-height: 0
父元素添加到一个。我完全忘记了为什么需要这样做。
最不幸的是,Microsoft Edge实施似乎只是半成品。至少,我在测试中有一些闪烁且未对齐的表格单元。该桌子仍然可用,但存在重大美学问题。
这是Mahes解决方案的变体.你可以这样称呼它$('table#foo').scrollableTable();
这个想法是:
thead
并tbody
分成单独的table
元素table
个div.scrollable
div.scrollable
实际滚动CSS可以是:
div.scrollable { height: 300px; overflow-y: scroll;}
Run Code Online (Sandbox Code Playgroud)
也就是说,它适用于我的目的,你可以随意采取和修改它.
这是插件:
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);
};
Run Code Online (Sandbox Code Playgroud)
:)
不那么干净,但纯粹的 HTML/CSS 解决方案。
table {
overflow-x:scroll;
}
tbody {
max-height: /*your desired max height*/
overflow-y:scroll;
display:block;
}
Run Code Online (Sandbox Code Playgroud)
更新了 IE8+ JSFiddle 示例
不知何故,我最终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%
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
198416 次 |
最近记录: |