参考文献:https://blog.csdn.net/huanghanqian/article/details/52668667(主要贡献了浮动表头的实现方法及思路)
https://www.cnblogs.com/dujingjie/p/4571943.html(主要贡献了例子的表格代码)
本文只是对第一个参考连接里面的浮动方法稍加修改。由于原连接里面的方法存在以下问题:
1.有水平方向上的滚动条的时候,浮动表头是不会跟随的。
2.需要手动完成对表头的复制工作,有点麻烦,而且需要同时给table以及th下的tr加指定的id
3.复制出来的表头的样式受第一步工作完成程度的影响,可能会与原表头不一样。
我对代码改动的地方有:
1.加入了更多原表头和浮动表头同步的尺寸信息,因此实现了保持两个表头在有水平滚动条的时候也是同步滚动的。
2.使用javascript自动的复制所需要的元素,原表格只需要在th下的tr上加id="mytr2",就可以了、
3.上一步复制时会连带上table的相关属性,这样就不会再单独为复制出来的表头设置样式了。我在自己的页面上(使用bootstrap4修饰的表格)没发现有太明显的问题。说明一点:我的样式基本都是设置在table、th、tr这三个上的,所以只复制了这三级的属性。
使用方法:
1.需要符合table包含在div里面,table下面是th,th下面是tr这种结构就可以。
2.把th下的tr的id设置成mytr2
3.引入jquery,应该是对版本不敏感
4.把下面的代码放到页面body标签内部的最下端
<script>
//使用时只要原表格符合 div>table>th>tr#mytr2,就可以直接使用下面的代码进行表头浮动
//浮动表头-用来复制一个表头
function copyMytr2Parent2NewTable() {
var ndiv = $("<div id='fixedTableHeader'></div>");
//下面这堆CSS是参考其他网友写的,我原封不动的写在这里了,有能力的可以优化一下
ndiv.css({
"display" : "none",
"position" : "fixed",
"top" : "0px",
"overflow" : "hidden",
"margin" : "0 auto",
"z-index" : "9999"
})
var ntable = $("<table></table");
//我的原表格是使用bootstrap4的,好像是类名决定样式,所以下面这步是从原来的表格上拷贝所有的属性(除id外)到复制出来的表格上
//获取原表格的node
var otable = $("#mytr2").parent().parent()[0]
//把原表格下除id外的所有的属性,原样设置给复制出来的表格
for (var attrIndex = 0; attrIndex < otable.attributes.length; attrIndex++) {
if (otable.attributes.item(attrIndex).name != "id") {
ntable.attr(otable.attributes.item(attrIndex).name,otable.attributes.item(attrIndex).value);
}
}
//把mytr2父元素复制到新表格下
ntable.append($("#mytr2").parent().clone());
//把复制出来的表头的th下的tr的id改成mytr1
ntable.children().children().attr("id", "mytr1");
//把复制出来的表格添加到单独的div里面
ndiv.append(ntable);
//把上面的div,就是包含了新表头的div放到现有表格的前面
$("#mytr2").parent().parent().parent().before(ndiv);
}
//更新浮动的表头
function updateFloatTheader() {
//遍历mytr1下面的每一个td
$('#mytr1').children().each(function(i, n) {
//当前td
var obj = $(n);
//更新为mytr2下对应td的宽
obj.width($('#mytr2').children().eq(i).width());
//更新为mytr2下对应的高,可以试下去掉,如果去掉后没有影响的话,可以注释掉
obj.height($('#mytr2').children().eq(i).height());
});
//设置整个浮动表头的左边偏移量
$('#fixedTableHeader').css("left",$("#mytr2").parent().parent()[0].getBoundingClientRect().left)
//同步两个table的宽度,防止出现错位的现象
$('#fixedTableHeader').children().width($("#mytr2").parent().parent().width())
}
//浮动表头需要的
$(function() {
//复制出浮动表头来
copyMytr2Parent2NewTable();
//更新浮动表头的位置
updateFloatTheader();
window.onresize = function() {
//窗口改变大小的时候更新浮动表头的位置
updateFloatTheader()
}
window.onscroll = function() {
if ($(document).scrollTop() > $("#mytr2").parent().parent().offset().top) {//判断是否滚动到了表头显示不出来的位置
$('#fixedTableHeader').show();
} else {
$('#fixedTableHeader').hide();
}
//更新浮动表头的位置
updateFloatTheader()
}
});
</script>
以下是一个样例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表格顶部悬浮效果</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
.container {
width: 980px;
margin: 0 auto;
}
.table {
background-color: #f0f0f0;
border:1px solid red;
}
.table thead {
height: 50px;
border:1px solid red;
}
.table tr td,
.table tr th {
padding: 20px;
text-align: center;
border:1px solid red;
}
</style>
</head>
<body>
<div class="top"></div>
<div>
<table class="table container">
<thead>
<tr id="mytr2">
<th>表头1</th>
<th>表头2</th>
<th>表头3</th>
<th>表头4</th>
<th>表头5</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>5</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
</div>
<script>
//使用时只要原表格符合 div>table>th>tr#mytr2,就可以直接使用下面的代码进行表头浮动
//浮动表头-用来复制一个表头
function copyMytr2Parent2NewTable() {
var ndiv = $("<div id='fixedTableHeader'></div>");
//下面这堆CSS是参考其他网友写的,我原封不动的写在这里了,有能力的可以优化一下
ndiv.css({
"display" : "none",
"position" : "fixed",
"top" : "0px",
"overflow" : "hidden",
"margin" : "0 auto",
"z-index" : "9999"
})
var ntable = $("<table></table");
//我的原表格是使用bootstrap4的,好像是类名决定样式,所以下面这步是从原来的表格上拷贝所有的属性(除id外)到复制出来的表格上
//获取原表格的node
var otable = $("#mytr2").parent().parent()[0]
//把原表格下除id外的所有的属性,原样设置给复制出来的表格
for (var attrIndex = 0; attrIndex < otable.attributes.length; attrIndex++) {
if (otable.attributes.item(attrIndex).name != "id") {
ntable.attr(otable.attributes.item(attrIndex).name,otable.attributes.item(attrIndex).value);
}
}
//把mytr2父元素复制到新表格下
ntable.append($("#mytr2").parent().clone());
//把复制出来的表头的th下的tr的id改成mytr1
ntable.children().children().attr("id", "mytr1");
//把复制出来的表格添加到单独的div里面
ndiv.append(ntable);
//把上面的div,就是包含了新表头的div放到现有表格的前面
$("#mytr2").parent().parent().parent().before(ndiv);
}
//更新浮动的表头
function updateFloatTheader() {
//遍历mytr1下面的每一个td
$('#mytr1').children().each(function(i, n) {
//当前td
var obj = $(n);
//更新为mytr2下对应td的宽
obj.width($('#mytr2').children().eq(i).width());
//更新为mytr2下对应的高,可以试下去掉,如果去掉后没有影响的话,可以注释掉
obj.height($('#mytr2').children().eq(i).height());
});
//设置整个浮动表头的左边偏移量
$('#fixedTableHeader').css("left",$("#mytr2").parent().parent()[0].getBoundingClientRect().left)
//同步两个table的宽度,防止出现错位的现象
$('#fixedTableHeader').children().width($("#mytr2").parent().parent().width())
}
//浮动表头需要的
$(function() {
//复制出浮动表头来
copyMytr2Parent2NewTable();
//更新浮动表头的位置
updateFloatTheader();
window.onresize = function() {
//窗口改变大小的时候更新浮动表头的位置
updateFloatTheader()
}
window.onscroll = function() {
if ($(document).scrollTop() > $("#mytr2").parent().parent().offset().top) {//判断是否滚动到了表头显示不出来的位置
$('#fixedTableHeader').show();
} else {
$('#fixedTableHeader').hide();
}
//更新浮动表头的位置
updateFloatTheader()
}
});
</script>
</body>
</html>