<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
因此,在上面的示例中,如果页面不可见,我希望
<thead>
与页面一起滚动。 br /> 重要提示:我不是在寻找
<tbody>
带有滚动条(溢出:自动)的解决方案。#1 楼
您可以通过在scroll
上使用window
事件处理程序,然后使用另一个具有固定位置的table
来在页面顶部显示标题,来执行此操作。HTML:
<table id="header-fixed"></table>
CSS:
#header-fixed {
position: fixed;
top: 0px; display:none;
background-color:white;
}
JavaScript:
var tableOffset = $("#table-1").offset().top;
var $header = $("#table-1 > thead").clone();
var $fixedHeader = $("#header-fixed").append($header);
$(window).bind("scroll", function() {
var offset = $(this).scrollTop();
if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
$fixedHeader.show();
}
else if (offset < tableOffset) {
$fixedHeader.hide();
}
});
当用户向下滚动足够远以隐藏原始表头时,将显示表头。当用户将页面再次滚动到足够远时,它将再次隐藏。
工作示例:http://jsfiddle.net/andrewwhitaker/fj8wM/
评论
我在想这个,但是如果标题列的宽度根据内容而改变怎么办?除非列宽固定,否则标题行可能不会与内容行对齐。只是一个想法。
–伊兹密尔·拉米雷斯(Yzmir Ramirez)
2011-1-17的4:09
如果列标题的名称短于列数据值,则此示例不起作用。尝试更改该小提琴以使其具有infoooooooo之类的值,而不是info。我在考虑克隆表时设置的某种硬编码宽度。
–whiterook6
13年6月24日在20:10
这具有主要限制,其中至少有一些限制是尝试在非窗口的容器中使用表时。 mkoryak.github.io/floatThead有一个更通用的解决方案。
– Y
2013年11月30日19:42
这可能会帮助需要动态th宽度的任何人,这是我最后要做的事情,它是@AndrewWhitaker的分支:jsfiddle.net/noahkoch/wLcjh/1
–诺亚·科赫(Noah Koch)
2014年4月7日在16:14
当原始单元格具有填充时,使用您的解决方案的@NoahKoch固定标头仍不能像原始头宽。我改进了您的解决方案,以向重复的单元格添加填充。 JSFiddle的分支:jsfiddle.net/1n23m69u/2
–fandasson
2015年1月23日的15:00
#2 楼
纯CSS(不支持IE11):table th {
position: -webkit-sticky; // this is for all Safari (Desktop & iOS), not for Chrome
position: sticky;
top: 0;
z-index: 5;
background: #fff;
}
评论
我什至看不到此功能在Chrome中正常工作。检查工具将-webkit-sticky显示为位置的无效值。
–卡门主义
17年5月24日在3:36
@carmenism -webkit-sticky适用于Safari(台式机和iOS),而不适用于Chrome。位置:sticky在版本56的Chrome中有效。您应该设置以下两个规则:-webkit-sticky,并且完全按照我的代码示例中的顺序进行粘贴。 Safari使Webkit变得粘滞,而所有其他浏览器均将其覆盖为粘滞。
–伊霍尔(Ihor Zenich)
17年5月24日13:54
我无法使它正常工作。从一个快速的谷歌看起来像位置:粘性将不适用于表元素。
–rjh
17年7月27日在7:26
申请为我工作的人:tablethead tr th ......
–nurp
18年5月6日在8:21
您必须将其应用于th,因为它不适用于thead或tr
–helado
19年4月29日在22:10
#3 楼
好吧,我试图获得相同的效果,而不求助于固定大小的列或整个表的固定高度。我想出的解决方案是破解。它包括复制整个表,然后隐藏标题以外的所有内容,并使其具有固定位置。
HTML
<div id="table-container">
<table id="maintable">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>some really long line here instead</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
<div id="bottom_anchor"></div>
</div>
CSS
body { height: 1000px; }
thead{
background-color:white;
}
javascript
function moveScroll(){
var scroll = $(window).scrollTop();
var anchor_top = $("#maintable").offset().top;
var anchor_bottom = $("#bottom_anchor").offset().top;
if (scroll>anchor_top && scroll<anchor_bottom) {
clone_table = $("#clone");
if(clone_table.length == 0){
clone_table = $("#maintable").clone();
clone_table.attr('id', 'clone');
clone_table.css({position:'fixed',
'pointer-events': 'none',
top:0});
clone_table.width($("#maintable").width());
$("#table-container").append(clone_table);
$("#clone").css({visibility:'hidden'});
$("#clone thead").css({'visibility':'visible','pointer-events':'auto'});
}
} else {
$("#clone").remove();
}
}
$(window).scroll(moveScroll);
请参见此处:http://jsfiddle.net/QHQGF/7/
编辑:更新了代码,以便thead可以接收指针事件(因此标题中的按钮和链接仍然有效)。这解决了luhfluh和Joe M报告的问题。
此处是新的jsfiddle:http://jsfiddle.net/cjKEx/
评论
我首先尝试过,这样做的问题是标题中元素的大小取决于表的内容。如果一行包含大量内容,那么整个列(包括标题)都会增加。如果仅克隆thead,则会丢失该信息,而不会获得预期的效果。请参阅Yzmir Ramirez对已接受答案的评论。这是我发现不使用固定宽度列的唯一方法。我知道这不干净,这就是我说这是hack的方式。
–熵
2011年12月22日在16:12
哦,我明白了。这种方法很棒,因为它适用于流体色谱柱,我用了一点点Google搜索,却找不到另一个具有该功能的方法。 Anywhay,如果我能以某种方式完成它,我会在这里提及
– M2_
2011-12-22 21:27
@luhfluh,是的,问题出在克隆表中,原因是指针事件:无。使用此选项可以使点击通过克隆并到达原始表。将其还原到克隆表的标题中,以便可单击标题(且仅标题)可解决此问题。我更新了我的帖子以反映这一点:)
–熵
2012年7月19日在23:16
在
–贾姆·维尔(Jam Ville)
2014年2月5日下午4:25
这个解决方案对我有用,一个小问题是表格是否延伸到屏幕的右边。如果用户向右滚动,则标题不会滚动。否则很好。
–kurdtpage
17年1月18日在22:21
#4 楼
我写了一个插件来做到这一点。我已经进行了大约一年的研究,我认为它可以很好地处理所有极端情况:在容器内滚动而溢出
在窗口内滚动
/>注意调整窗口大小时会发生什么
将事件绑定到标题上
最重要的是,它不会强迫您更改表的css以使其正常工作
/>
以下是一些演示/文档:http://mkoryak.github.io/floatThead/
评论
付出了很大的努力,但不适用于IE 10,并且在调整firefox23 / ubuntu上的窗口大小方面有些古怪。
–詹宁
2013年9月11日上午7:45
仅供参考:我已解决IE9和10最新版本的问题。
–mkoryak
13-10-3在4:02
您可以制作不需要jQuery的版本吗?
–Curtis W
2014年7月23日23:00
可能是因为他不使用jquery ...而且不-我不会制作不使用jquery的版本。
–mkoryak
2015年3月8日下午1:00
我使用了一个简单的jQery tablesorter插件,根据您的常见问题解答,您的插件不喜欢大多数CSS规则,例如#sortable td {..}等。我尝试进行一些调整,但是无法正常工作。
– masche
16年4月1日在9:40
#5 楼
我能够通过更改列宽来解决此问题。我从上面的安德鲁解决方案开始(非常感谢!),然后添加了一个小循环来设置克隆的td的宽度:$("#header-fixed td").each(function(index){
var index2 = index;
$(this).width(function(index2){
return $("#table-1 td").eq(index).width();
});
});
复制整个表格并隐藏正文。我是JavaScript和jQuery(和栈溢出)的新手,因此感谢您提出任何评论。
评论
工作正常,但我需要添加以下行$(“#header-fixed”)。width($(“#table-1”)。width());使列正确排列。
–伊利亚·费多托夫(Ilya Fedotov)
13年5月21日在20:31
#6 楼
这是迄今为止我发现的具有固定表头的最佳解决方案。UPDATE 5/11:修正了Kerry Johnson指出的水平滚动错误
Codepen :https://codepen.io/josephting/pen/demELL
;(function($) {
$.fn.fixMe = function() {
return this.each(function() {
var $this = $(this),
$t_fixed;
function init() {
$this.wrap('<div class="container" />');
$t_fixed = $this.clone();
$t_fixed.find("tbody").remove().end().addClass("fixed").insertBefore($this);
resizeFixed();
}
function resizeFixed() {
$t_fixed.width($this.outerWidth());
$t_fixed.find("th").each(function(index) {
$(this).css("width",$this.find("th").eq(index).outerWidth()+"px");
});
}
function scrollFixed() {
var offsetY = $(this).scrollTop(),
offsetX = $(this).scrollLeft(),
tableOffsetTop = $this.offset().top,
tableOffsetBottom = tableOffsetTop + $this.height() - $this.find("thead").height(),
tableOffsetLeft = $this.offset().left;
if(offsetY < tableOffsetTop || offsetY > tableOffsetBottom)
$t_fixed.hide();
else if(offsetY >= tableOffsetTop && offsetY <= tableOffsetBottom && $t_fixed.is(":hidden"))
$t_fixed.show();
$t_fixed.css("left", tableOffsetLeft - offsetX + "px");
}
$(window).resize(resizeFixed);
$(window).scroll(scrollFixed);
init();
});
};
})(jQuery);
$(document).ready(function(){
$("table").fixMe();
$(".up").click(function() {
$('html, body').animate({
scrollTop: 0
}, 2000);
});
});
body{
font:1.2em normal Arial,sans-serif;
color:#34495E;
}
h1{
text-align:center;
text-transform:uppercase;
letter-spacing:-2px;
font-size:2.5em;
margin:20px 0;
}
.container{
width:90%;
margin:auto;
}
table{
border-collapse:collapse;
width:100%;
}
.blue{
border:2px solid #1ABC9C;
}
.blue thead{
background:#1ABC9C;
}
.purple{
border:2px solid #9B59B6;
}
.purple thead{
background:#9B59B6;
}
thead{
color:white;
}
th,td{
text-align:center;
padding:5px 0;
}
tbody tr:nth-child(even){
background:#ECF0F1;
}
tbody tr:hover{
background:#BDC3C7;
color:#FFFFFF;
}
.fixed{
top:0;
position:fixed;
width:auto;
display:none;
border:none;
}
.scrollMore{
margin-top:600px;
}
.up{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>↓ SCROLL ↓</h1>
<table class="blue">
<thead>
<tr>
<th>Colonne 1</th>
<th>Colonne 2</th>
<th>Colonne 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Non</td>
<td>MaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
</tbody>
</table>
<h1 class="scrollMore">↓ SCROLL MORE ↓</h1>
<table class="purple">
<thead>
<tr>
<th>Colonne 1</th>
<th>Colonne 2</th>
<th>Colonne 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
</tbody>
</table>
<h1 class="up scrollMore">↑ UP ↑</h1>
评论
我修复了此脚本,以便它可以处理具有边框和内边距的
–alanng
16年6月21日,0:05
您可能还需要在.fixed类的某个正数上添加z-index的CSS属性,以便在滚动页面时在页面加载后呈现的对象不会浮在固定标头之上。
–alanng
16 Jun 21'在0:12
简单实用。
– RitchieD
17年6月6日在15:42
如何动态处理最高职位。假设我需要向上滚动到我的主页固定标题内容下方。 .fixed {top:0;}。
–VijayVishnu
17年12月11日13:09
@KerryJohnson感谢您的来信。我进行了一些更改,因此它支持水平滚动和动态列宽。
–约瑟夫
18年5月11日在4:22
#7 楼
这里已经有很多非常好的解决方案。但在这些情况下,我使用的最简单的仅CSS解决方案之一如下: table {
/* Not required only for visualizing */
border-collapse: collapse;
width: 100%;
}
table thead tr th {
/* Important */
background-color: red;
position: sticky;
z-index: 100;
top: 0;
}
td {
/* Not required only for visualizing */
padding: 1em;
}
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
由于不需要JavaScript,因此可以大大简化这种情况。本质上,您需要专注于第二条CSS规则,其中包含确保无论滚动空间如何,表头仍位于顶部的条件。
详细说明每条规则。
position
旨在向浏览器指示头对象,其行及其单元格都需要粘贴在顶部。这必需要伴随top
,它向浏览器指定头部将停留在页面或视口的顶部。此外,可以添加z-index
以确保头部的内容始终位于顶部。背景颜色仅用于说明问题所在。您无需使用任何其他JavaScript即可获得此效果。 2016年之后,大多数主流浏览器都支持此功能。
评论
imo是最简单,最干净的答案,总有一种简单的方法可以解决一个问题,情况就是这样。即使我将ng-repeat与angularjs一起使用,它的工作方式也很吸引人。
–David Castro
19/12/2在23:37
#8 楼
最好的解决方案是使用此jquery插件:https://github.com/jmosbech/StickyTableHeaders
此插件对我们来说非常有用,我们尝试了许多其他解决方案。我们在IE,Chrome和Firefox中对其进行了测试
评论
您是否知道任何解决方案还保留了标头中的剔除数据绑定控件的功能?
–Csaba Toth
14年7月17日在17:21
不适用于我:标头位于表格之外,并且即使使用“ scrollableArea”选项也仍停留在浏览器顶部(窗口)。我看到之前提到的内容没有附加评论。也许它需要他使用的CSS,但CSS无法使用。
– Exel Gamboa
17年6月30日在14:44
#9 楼
我找到了一个名为Sticky Table Headers的简单jQuery库。两行代码,它确实实现了我想要的功能。上面的解决方案无法管理列宽,因此,如果表单元格占用大量空间,则持久标头的最终大小将与表的宽度不匹配。http:/ /plugins.jquery.com/StickyTableHeaders/
此处的使用信息:
https://github.com/jmosbech/StickyTableHeaders
#10 楼
我找到了一个不使用JQuery且不使用CSS的简单解决方案。您必须将固定内容放入'th'标记内并添加CSS
table th {
position:sticky;
top:0;
z-index:1;
border-top:0;
background: #ededed;
}
位置z -index和top属性就足够了。但是您可以应用其余的部分以获得更好的视图。
评论
这与两年前发布的Ihor Zenich的答案有何不同?
– codepearlex
8月8日在16:53
#11 楼
好吧,在回顾了所有可用的解决方案之后,我编写了插件,该插件可以冻结页面或容器顶部的任何行(不仅是行)。这非常简单而且非常快速。随时使用它。http://maslianok.github.io/stickyRows/
#12 楼
您可以使用这种方法,纯HTML和CSS不需要JS :) .table-fixed-header {
display: flex;
justify-content: space-between;
margin-right: 18px
}
.table-fixed {
display: flex;
justify-content: space-between;
height: 150px;
overflow: scroll;
}
.column {
flex-basis: 24%;
border-radius: 5px;
padding: 5px;
text-align: center;
}
.column .title {
border-bottom: 2px grey solid;
border-top: 2px grey solid;
text-align: center;
display: block;
font-weight: bold;
}
.cell {
padding: 5px;
border-right: 1px solid;
border-left: 1px solid;
}
.cell:nth-of-type(even) {
background-color: lightgrey;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Fixed header Bin</title>
</head>
<body>
<div class="table-fixed-header">
<div class="column">
<span class="title">col 1</span>
</div>
<div class="column">
<span class="title">col 2</span>
</div>
<div class="column">
<span class="title">col 3</span>
</div>
<div class="column">
<span class="title">col 4</span>
</div>
</div>
<div class="table-fixed">
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
</div>
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
</div>
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
<div class="cell">beta</div>
<div class="cell">beta</div>
<div class="cell">beta</div>
</div>
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
</div>
</div>
</body>
</html>
#13 楼
我也遇到了同样的问题,边框格式没有使用entrophy的代码显示,但是做了一些小小的修复,现在该表是可扩展的,并显示了您可能添加的所有css样式规则。到css add:
#maintable{width: 100%}
然后这里是新的javascript:
function moveScroll(){
var scroll = $(window).scrollTop();
var anchor_top = $("#maintable").offset().top;
var anchor_bottom = $("#bottom_anchor").offset().top;
if (scroll > anchor_top && scroll < anchor_bottom) {
clone_table = $("#clone");
if(clone_table.length === 0) {
clone_table = $("#maintable").clone();
clone_table.attr({id: "clone"})
.css({
position: "fixed",
"pointer-events": "none",
top:0
})
.width($("#maintable").width());
$("#table-container").append(clone_table);
// dont hide the whole table or you lose border style &
// actively match the inline width to the #maintable width if the
// container holding the table (window, iframe, div) changes width
$("#clone").width($("#maintable").width());
// only the clone thead remains visible
$("#clone thead").css({
visibility:"visible"
});
// clone tbody is hidden
$("#clone tbody").css({
visibility:"hidden"
});
// add support for a tfoot element
// and hide its cloned version too
var footEl = $("#clone tfoot");
if(footEl.length){
footEl.css({
visibility:"hidden"
});
}
}
}
else {
$("#clone").remove();
}
}
$(window).scroll(moveScroll);
评论
就标题中的边框格式而言,这确实比熵的解决方案更好。但是,在当前的Firefox(而不是Chrome)中,一旦开始滚动,它将在表格下方创建可见的单元边界工件。
–alanng
16年6月20日在2:37
#14 楼
这是一个基于公认答案的解决方案。它会更正以下内容:列宽,匹配的表样式以及在容器div中滚动表时。用法
确保您的表具有
<thead>
标记,因为仅主题内容将被修复。$("#header-fixed").fixHeader();
JavaSript
//Custom JQuery Plugin
(function ($) {
$.fn.fixHeader = function () {
return this.each(function () {
var $table = $(this);
var $sp = $table.scrollParent();
var tableOffset = $table.position().top;
var $tableFixed = $("<table />")
.prop('class', $table.prop('class'))
.css({ position: "fixed", "table-layout": "fixed", display: "none", "margin-top": "0px" });
$table.before($tableFixed);
$tableFixed.append($table.find("thead").clone());
$sp.bind("scroll", function () {
var offset = $(this).scrollTop();
if (offset > tableOffset && $tableFixed.is(":hidden")) {
$tableFixed.show();
var p = $table.position();
var offset = $sp.offset();
//Set the left and width to match the source table and the top to match the scroll parent
$tableFixed.css({ left: p.left + "px", top: (offset ? offset.top : 0) + "px", }).width($table.width());
//Set the width of each column to match the source table
$.each($table.find('th, td'), function (i, th) {
$($tableFixed.find('th, td')[i]).width($(th).width());
});
}
else if (offset <= tableOffset && !$tableFixed.is(":hidden")) {
$tableFixed.hide();
}
});
});
};
})(jQuery);
评论
这对我来说很好。唯一的问题是需要水平滚动的表的问题。我在JSFiddle中进行了更新,这里jsfiddle.net/4mgneob1/1我减去了$ sp.scrollLeft(),它从左开始滚动量,因此在向下滚动固定表时位置正确。还添加了在水平滚动时是否可以看到固定表格以检查左侧位置的检查功能。我无法解决的另一个问题是,当表格位于视口上方时,固定表格应该隐藏,直到用户向上滚动为止。
– Henesnarfel
15/09/14在18:10
引发TypeError错误:$ table.scrollParent不是函数
–卡林根
15年11月11日在20:41
#15 楼
这将帮助您拥有一个固定的标头,该标头也可以与数据一起水平滚动。<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Shubh</title>
<script type="text/javascript">
var lastSeen = [ 0, 0 ];
function checkScroll(div1, div2) {
if (!div1 || !div2)
return;
var control = null;
if (div1.scrollLeft != lastSeen[0])
control = div1;
else if (div2.scrollLeft != lastSeen[1])
control = div2;
if (control == null)
return;
else
div1.scrollLeft = div2.scrollLeft = control.scrollLeft;
lastSeen[0] = div1.scrollLeft;
lastSeen[1] = div2.scrollLeft;
}
window
.setInterval(
"checkScroll(document.getElementById('innertablediv'), document.getElementById('headertable'))",
1);
</script>
<style type="text/css">
#full {
width: 400px;
height: 300px;
}
#innertablediv {
height: 200px;
overflow: auto;
}
#headertable {
overflow: hidden;
}
</style>
</head>
<body>
<div id="full">
<div id="headertable">
<table border="1" bgcolor="grey" width="150px" id="headertable">
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td> </td>
</tr>
</table>
</div>
<div id="innertablediv">
<table border="1" id="innertableid">
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
</table>
</div>
</div>
</body>
</html>
评论
这将帮助您拥有一个固定的标题,该标题也可以与数据一起水平滚动。
–user2669926
13年8月10日在6:35
#16 楼
function fix_table_header_position(){
var width_list = [];
$("th").each(function(){
width_list.push($(this).width());
});
$("tr:first").css("position", "absolute");
$("tr:first").css("z-index", "1000");
$("th, td").each(function(index){
$(this).width(width_list[index]);
});
$("tr:first").after("<tr height=" + $("tr:first").height() + "></tr>");}
这是我的解决方案
#17 楼
聚会有点晚了,但这是一个实现,可在同一页面上使用多个表,并且“垃圾”免费(使用requestAnimationFrame)。同样,也不需要在列上提供任何宽度。水平滚动也可以。标题是在
div
中定义的,因此您可以根据需要随意在其中添加任何标记(如按钮)。这就是所有需要的HTML:<div class="tbl-resp">
<table id="tbl1" class="tbl-resp__tbl">
<thead>
<tr>
<th>col 1</th>
<th>col 2</th>
<th>col 3</th>
</tr>
</thead>
</table>
</div>
https://jsfiddle.net/lloydleo/bk5pt5gs/
#18 楼
在此解决方案中,动态创建固定标头,从THEAD克隆内容和样式,您只需要两行,例如:
var $myfixedHeader = $("#Ttodo").FixedHeader(); //create fixed header
$(window).scroll($myfixedHeader.moveScroll); //bind function to scroll event
下面提供的我的jquery插件FixedHeader和
getStyleObject可以放入文件.js
// JAVASCRIPT
/*
* getStyleObject Plugin for jQuery JavaScript Library
* From: http://upshots.org/?p=112
Basic usage:
$.fn.copyCSS = function(source){
var styles = $(source).getStyleObject();
this.css(styles);
}
*/
(function($){
$.fn.getStyleObject = function(){
var dom = this.get(0);
var style;
var returns = {};
if(window.getComputedStyle){
var camelize = function(a,b){
return b.toUpperCase();
};
style = window.getComputedStyle(dom, null);
for(var i = 0, l = style.length; i < l; i++){
var prop = style[i];
var camel = prop.replace(/\-([a-z])/g, camelize);
var val = style.getPropertyValue(prop);
returns[camel] = val;
};
return returns;
};
if(style = dom.currentStyle){
for(var prop in style){
returns[prop] = style[prop];
};
return returns;
};
return this.css();
}
})(jQuery);
//Floating Header of long table PiotrC
(function ( $ ) {
var tableTop,tableBottom,ClnH;
$.fn.FixedHeader = function(){
tableTop=this.offset().top,
tableBottom=this.outerHeight()+tableTop;
//Add Fixed header
this.after('<table id="fixH"></table>');
//Clone Header
ClnH=$("#fixH").html(this.find("thead").clone());
//set style
ClnH.css({'position':'fixed', 'top':'0', 'zIndex':'60', 'display':'none',
'border-collapse': this.css('border-collapse'),
'border-spacing': this.css('border-spacing'),
'margin-left': this.css('margin-left'),
'width': this.css('width')
});
//rewrite style cell of header
$.each(this.find("thead>tr>th"), function(ind,val){
$(ClnH.find('tr>th')[ind]).css($(val).getStyleObject());
});
return ClnH;}
$.fn.moveScroll=function(){
var offset = $(window).scrollTop();
if (offset > tableTop && offset<tableBottom){
if(ClnH.is(":hidden"))ClnH.show();
$("#fixH").css('margin-left',"-"+$(window).scrollLeft()+"px");
}
else if (offset < tableTop || offset>tableBottom){
if(!ClnH.is(':hidden'))ClnH.hide();
}
};
})( jQuery );
var $myfixedHeader = $("#repTb").FixedHeader();
$(window).scroll($myfixedHeader.moveScroll);
/* CSS - important only NOT transparent background */
#repTB{border-collapse: separate;border-spacing: 0;}
#repTb thead,#fixH thead{background: #e0e0e0 linear-gradient(#d8d8d8 0%, #e0e0e0 25%, #e0e0e0 75%, #d8d8d8 100%) repeat scroll 0 0;border:1px solid #CCCCCC;}
#repTb td{border:1px solid black}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>example</h3>
<table id="repTb">
<thead>
<tr><th>Col1</th><th>Column2</th><th>Description</th></tr>
</thead>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
</table>
#19 楼
创建具有与主表相同的标题的额外表。只需将thead放入一行包含所有标题的新表中即可。绝对位置和背景白色。对于主表,将其放在div中并使用一些高度和y滚动。这样,我们的新表将克服主表的标题并停留在该位置。将所有内容包围在一个div中。以下是执行此操作的粗略代码。 <div class="col-sm-8">
<table id="header-fixed" class="table table-bordered table-hover" style="width: 351px;position: absolute;background: white;">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
</table>
<div style="height: 300px;overflow-y: scroll;">
<table id="tableMain" class="table table-bordered table-hover" style="table-layout:fixed;overflow-wrap: break-word;cursor:pointer">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
</div>
</div>
#20 楼
div.wrapper {
padding:20px;
}
table.scroll thead {
width: 100%;
background: #FC6822;
}
table.scroll thead tr:after {
content: '';
overflow-y: scroll;
visibility: hidden;
}
table.scroll thead th {
flex: 1 auto;
display: block;
color: #fff;
}
table.scroll tbody {
display: block;
width: 100%;
overflow-y: auto;
height: auto;
max-height: 200px;
}
table.scroll thead tr,
table.scroll tbody tr {
display: flex;
}
table.scroll tbody tr td {
flex: 1 auto;
word-wrap: break;
}
table.scroll thead tr th,
table.scroll tbody tr td {
width: 25%;
padding: 5px;
text-align-left;
border-bottom: 1px solid rgba(0,0,0,0.3);
}
<div class="wrapper">
<table border="0" cellpadding="0" cellspacing="0" class="scroll">
<thead>
<tr>
<th>Name</th>
<th>Vorname</th>
<th>Beruf</th>
<th>Alter</th>
</tr>
</thead>
<tbody>
<tr>
<td>Müller</td>
<td>Marie</td>
<td>Künstlerin</td>
<td>26</td>
</tr>
<tr>
<td>Meier</td>
<td>Stefan</td>
<td>Chemiker</td>
<td>52</td>
</tr>
<tr>
<td>Schmidt</td>
<td>Sabrine</td>
<td>Studentin</td>
<td>38</td>
</tr>
<tr>
<td>Mustermann</td>
<td>Max</td>
<td>Lehrer</td>
<td>41</td>
</tr>
<tr>
<td>Müller</td>
<td>Marie</td>
<td>Künstlerin</td>
<td>26</td>
</tr>
<tr>
<td>Meier</td>
<td>Stefan</td>
<td>Chemiker</td>
<td>52</td>
</tr>
<tr>
<td>Schmidt</td>
<td>Sabrine</td>
<td>Studentin</td>
<td>38</td>
</tr>
<tr>
<td>Mustermann</td>
<td>Max</td>
<td>Lehrer</td>
<td>41</td>
</tr>
<tr>
<td>Müller</td>
<td>Marie</td>
<td>Künstlerin</td>
<td>26</td>
</tr>
<tr>
<td>Meier</td>
<td>Stefan</td>
<td>Chemiker</td>
<td>52</td>
</tr>
<tr>
<td>Schmidt</td>
<td>Sabrine</td>
<td>Studentin</td>
<td>38</td>
</tr>
<tr>
<td>Mustermann</td>
<td>Max</td>
<td>Lehrer</td>
<td>41</td>
</tr>
</tbody>
</table>
</div>
演示:css固定表头演示
#21 楼
使用此解决您的问题tbody {
display: table-caption;
height: 200px;
caption-side: bottom;
overflow: auto;
}
#22 楼
我找到了没有jquery的解决方案HTML HTML
<table class="fixed_header">
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>row 1-0</td>
<td>row 1-1</td>
<td>row 1-2</td>
<td>row 1-3</td>
<td>row 1-4</td>
</tr>
<tr>
<td>row 2-0</td>
<td>row 2-1</td>
<td>row 2-2</td>
<td>row 2-3</td>
<td>row 2-4</td>
</tr>
<tr>
<td>row 3-0</td>
<td>row 3-1</td>
<td>row 3-2</td>
<td>row 3-3</td>
<td>row 3-4</td>
</tr>
<tr>
<td>row 4-0</td>
<td>row 4-1</td>
<td>row 4-2</td>
<td>row 4-3</td>
<td>row 4-4</td>
</tr>
<tr>
<td>row 5-0</td>
<td>row 5-1</td>
<td>row 5-2</td>
<td>row 5-3</td>
<td>row 5-4</td>
</tr>
<tr>
<td>row 6-0</td>
<td>row 6-1</td>
<td>row 6-2</td>
<td>row 6-3</td>
<td>row 6-4</td>
</tr>
<tr>
<td>row 7-0</td>
<td>row 7-1</td>
<td>row 7-2</td>
<td>row 7-3</td>
<td>row 7-4</td>
</tr>
</tbody>
</table>
CSS
.fixed_header{
width: 400px;
table-layout: fixed;
border-collapse: collapse;
}
.fixed_header tbody{
display:block;
width: 100%;
overflow: auto;
height: 100px;
}
.fixed_header thead tr {
display: block;
}
.fixed_header thead {
background: black;
color:#fff;
}
.fixed_header th, .fixed_header td {
padding: 5px;
text-align: left;
width: 200px;
}
您可以在这里看到它的工作:
https://jsfiddle.net/lexsoul/fqbsty3h
来源:https://medium.com/@vembarrajan/html-css-tricks-scroll -able-table-body-tbody-d23182ae0fbc
#23 楼
这可以通过使用样式属性转换来实现。您要做的就是将表包装到固定高度且溢出设置为auto的div中,例如:
.tableWrapper {
overflow: auto;
height: calc( 100% - 10rem );
}
然后可以在其上附加onscroll处理程序,这里有一个方法可以找到用
<div class="tableWrapper"></div>
包装的每个表: fixTables () {
document.querySelectorAll('.tableWrapper').forEach((tableWrapper) => {
tableWrapper.addEventListener('scroll', () => {
var translate = 'translate(0,' + tableWrapper.scrollTop + 'px)'
tableWrapper.querySelector('thead').style.transform = translate
})
})
}
这是工作示例实际应用中(我已经使用引导程序使其更漂亮了):小提琴
对于那些也想支持IE和Edge的人,以下是代码段:
fixTables () {
const tableWrappers = document.querySelectorAll('.tableWrapper')
for (let i = 0, len = tableWrappers.length; i < len; i++) {
tableWrappers[i].addEventListener('scroll', () => {
const translate = 'translate(0,' + tableWrappers[i].scrollTop + 'px)'
const headers = tableWrappers[i].querySelectorAll('thead th')
for (let i = 0, len = headers.length; i < len; i++) {
headers[i].style.transform = translate
}
})
}
}
在IE和Edge中滚动有点滞后...但是可以用
这里的答案可以帮助我找出答案:答案
#24 楼
我尝试了大多数这些解决方案,并最终找到(IMO)最佳,现代的解决方案:CSS网格
使用CSS网格,您可以定义一个“网格”,您最终可以为具有固定标题和可滚动内容的表创建一个不错的,无JavaScript,跨浏览器的解决方案。标头的高度甚至可以动态变化。
CSS:显示为网格,并设置
template-rows
的数量:.grid {
display: grid;
grid-template-rows: 50px auto; // For fixed height header
grid-template-rows: auto auto; // For dynamic height header
}
HTML:创建网格容器和已定义的
rows
的数量:<div class="grid">
<div></div>
<div></div>
</div>
这里是工作示例:
CSS
body {
margin: 0px;
padding: 0px;
text-align: center;
}
.table {
width: 100%;
height: 100%;
display: grid;
grid-template-rows: 50px auto;
}
.table-heading {
background-color: #ddd;
}
.table-content {
overflow-x: hidden;
overflow-y: scroll;
}
HTML
<html>
<head>
</head>
<body>
<div class="table">
<div class="table-heading">
HEADING
</div>
<div class="table-content">
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
</div>
</div>
</body>
</html>
#25 楼
我已经尝试过使用transformation:translate。尽管它在Firefox和Chrome中运行良好,但IE11中根本没有任何功能。没有双滚动条。支持表脚和标题。纯Javascript,没有jQuery。http://jsfiddle.net/wbLqzrfb/42/
thead.style.transform="translate(0,"+(dY-top-1)+"px)";
评论
重复? stackoverflow.com/questions/1030043查看大表时,在窗口顶部始终可见HTML表标题的可能重复项
我回答了另一个问题,请看看。 stackoverflow.com/a/56764334/9388978