当用户使用 jQuery 将表头滚出视图时,表头保持固定在顶部

我试图设计一个 HTML 表,其中的标题将留在页面的顶部时,AND 只有当用户滚动它出视图。例如,表格可能是500像素以下的页面,我如何做到这一点,如果用户滚动的标题看不到(浏览器检测到它不再在窗口视图) ,它将留在顶部?有人能给我一个 Javascript 解决方案吗?

<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>在页面出现在视野之外时能够随页面一起滚动。

重要: 我是 没有寻找一个解决方案,其中的 <tbody>将有一个滚动条(溢出: 自动)。

572727 次浏览

您可以这样做,利用 window上的 scroll事件处理程序,并使用另一个具有固定位置的 table在页面顶部显示标题。

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();
}
});
#header-fixed {
position: fixed;
top: 0px;
display: none;
background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table-1">
<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>
<table id="header-fixed"></table>

当用户向下滚动到足以隐藏原始表头时,这将显示表头。当用户再次将页面向上滚动到足够远时,它将再次隐藏。

工作示例: https://jsfiddle.net/andrewwhitaker/fj8wM/

我试图在不使用固定大小的列或为整个表设置固定高度的情况下获得同样的效果。

我想到的解决办法是黑进去。它包括复制整个表,然后隐藏除标题以外的所有内容,并使标题具有固定的位置。

超文本标示语言

<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/

编辑: 更新代码,使头部可以接收指针事件(使按钮和链接在头部仍然工作)。这修复了 luhfluh 和 Joe M 报告的问题。

这里是新的 jsfiddle: http://jsfiddle.net/cjKEx/

我能够修复改变列宽度的问题。我从上面安德鲁的解决方案开始(非常感谢!)然后添加一个小循环来设置克隆的 td 的宽度:

$("#header-fixed td").each(function(index){
var index2 = index;
$(this).width(function(index2){
return $("#table-1 td").eq(index).width();
});
});

这就解决了这个问题,而不必克隆整个表并隐藏主体。我对 JavaScript 和 jQuery (以及堆栈溢出)是全新的,所以任何评论都是值得赞赏的。

我也经历了同样的问题,边界格式没有显示使用熵的代码,但一些小修复,现在表是可扩展的,并显示所有 CSS 样式规则,你可以添加。

在 css 中添加:

#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);

这将帮助您有一个固定的标题,也可以与数据水平滚动。

<!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>&nbsp;&nbsp;&nbsp;</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>

我写了一个插件来做这个。我已经研究了大约一年了,我认为它能很好地处理所有的边缘案件:

  • 在有溢出的容器中滚动
  • 在窗口内滚动
  • 注意调整窗口大小时会发生什么
  • 将事件绑定到标题
  • 最重要的是,它不会强迫您更改表的 css 以使其正常工作

以下是一些演示/文档:
Http://mkoryak.github.io/floatthead/

最好的解决方案是使用这个 jquery 插件:

Https://github.com/jmosbech/stickytableheaders

这个插件非常适合我们,我们尝试了很多其他的解决方案。我们在 IE,Chrome 和 Firefox 中测试了它

我发现了一个简单的 jQuery 库,名为 Sticky Table Header。两行代码,就完全达到了我的要求。上面的解决方案不管理列宽,所以如果表单元格占用了大量空间,持久标头的结果大小将不会与表的宽度匹配。

Http://plugins.jquery.com/stickytableheaders/

使用说明: Https://github.com/jmosbech/stickytableheaders

到目前为止,这是我找到的最好的固定表头的解决方案。

更新5/11: 修正了 凯莉 · 约翰逊指出的水平滚动错误

编码: 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>&darr; SCROLL &darr;</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">&darr; SCROLL MORE &darr;</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">&uarr; UP &uarr;</h1>

这里有一个建立在公认答案基础上的解决方案。它更正了: 列宽度、匹配的表格样式以及在容器 div 中滚动表格的时间。

用法

确保您的表具有 <thead>标记,因为只有头部内容是固定的。

$("#header-fixed").fixHeader();

JavaScript

//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);
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>");}

这就是我的解决办法

在这个解决方案中,动态创建固定的头, 内容和风格是从 THEAD 克隆出来的

你只需要两句话,例如:

Var $myfixedHeader = $(“ # Ttodo”) 滚动($myfixedHeader.moveScroll) ;//绑定函数到滚动事件

我的 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>

有点晚了,但是这里有一个实现,它可以在同一个页面上处理多个表,并且可以“ jank”free (使用 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/

纯 CSS (不支持 IE11) :

table th {
position: -webkit-sticky; // this is for all Safari (Desktop & iOS), not for Chrome
position: sticky;
top: 0;
z-index: 1; // any positive value, layer order is global
background: #fff; // any bg-color to overlap
}

这可以通过使用样式属性转换来实现。 你所要做的就是把你的桌子包装成固定高度的 div,溢出设置为 auto,例如:

.tableWrapper {
overflow: auto;
height: calc( 100% - 10rem );
}

然后,你可以附加到它的滚动处理程序,这里你有方法,发现每个表与 <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
})
})
}

下面是一个实际应用的例子(我使用 bootstrap 使它更漂亮) : 小提琴

对于那些也想支持 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 中,滚动有一点延迟... 但它是有效的

下面是帮助我找到答案的答案: 回答

创建与主表具有相同标头的额外表。只需将 head 放入新表中,其中包含一行和所有标题。做位置绝对和背景白色。对于主表,将其放在一个 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>

您可以使用这种方法,纯 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>

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>

演示: < a href = “ https://www.reviloDesign.de/blog/css-trick/css-table-header-fix-thead-eine-tabelle-fixieren/”rel = “ nofollow noReferrer”> css 固定表头演示

我尝试了这些解决方案中的大部分,最终发现(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>
<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>

我试过用 翻译。虽然它在 Firefox 和 Chrome 中运行良好,但在 IE11中没有任何功能。没有双滚动条。支持表脚和标题。纯 Javascript,没有 jQuery。

Http://jsfiddle.net/wblqzrfb/42/

thead.style.transform="translate(0,"+(dY-top-1)+"px)";

解决你的问题

tbody {
display: table-caption;
height: 200px;
caption-side: bottom;
overflow: auto;
}

我找到了一个没有 jquery 的解决方案

超文本标示语言

<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

这里已经有很多很好的解决方案了。但是我在这种情况下使用的最简单的 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年以后,大多数主流浏览器都支持这一点。

我发现了一个简单的解决方案,没有使用 JQuery,只使用 CSS

您必须将固定的内容放在‘ th’标签中,并添加 CSS

table th {
position:sticky;
top:0;
z-index:1;
border-top:0;
background: #ededed;
}
   

位置、 z-index 和 top 属性就足够了,但是你可以应用其他属性来获得更好的视图。

在我的例子中,我只使用了 css:

首先我们需要这样的表格格式:

<table>
<thead><tr><th></th></tr></thead>
<tbody><tr><td></td><tr></tbody>
</table>

然后应用这个 css:

tbody {
display:block;
max-height:280px;
overflow-x: hidden;
overflow-y: auto;
}
thead, tbody tr {
display:table;
width:100%;
table-layout:fixed;
}

头部固定

最简单的 CSS,这将工作单行和多行的表头了

 /* CSS */


.fix-head-table thead {
position: sticky;
top: 0;
}


.fix-head-table thead th{
box-shadow: inset 0px 0px 0px 0.5px rgb(192 192 192);
border: none;
}

您可以根据需要修改开发人员窗口 css (检查元素)中的 box-shadow 插入“0.5 px”阴影扩展值,还可以修改该阴影的颜色

下面的代码工作完美,尝试!

<style>
table th {
background-color:gray;
color:#fff;
}
table td {
text-align:center;
color:#000;
}
</style>
<table style='width:100%;'>
<tr style="position: -webkit-sticky; position: sticky; top: 0;">
<th>Hour</th>
<th>Start</th>
<th>End</th>
<th>Pcs</th>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>555</td>
<td>666</td>
<td>777</td>
<td>888</td>
</tr>
<tr>
<td>999</td>
<td>1010</td>
<td>1212</td>
<td>1414</td>
</tr>
<tr>
<td>1515</td>
<td>1616</td>
<td>1717</td>
<td>1818</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
</table>