最近碰到这样一个需求,需要固定表头以及列的表格,而且表格需要实现拖拽功能。
实现固定表头以及列的表格
1. stick以及table-layout来实现
主要是使用2个css属性
- table-layout: fixed 表格和列的宽度通过表格的宽度来设置,某一列的宽度仅由该列首行的单元格决定。在当前列中,该单元格所在行之 后的行并不会影响整个列宽。
table {
table-layout: fixed;
width: 100%;
}
- position:sticky 根据正常文档流进行定位,相对它的最近滚动祖先,基于top,right,bottom和left的值进行偏移。偏移值不会影响任何其他的元素。 sticky的表现相似于relative和fixed的合体,在超过目标区域时,他会固定于目标位置。
thead tr th{
position:sticky;
top:0;
}
代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>React Webpack Template Title</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
.test-table {
width:800px;
height:240px; /* 固定高度 */
margin: 0 auto;
border:1px solid gray;
border-bottom: 0;
border-right: 0;
text-align: center;
overflow:auto;
}
td, th {
border-right :1px solid gray;
border-bottom :1px solid gray;
width:100px;
height:30px;
box-sizing: border-box;
}
th {
background-color:lightblue;
}
table {
border-collapse:separate;
table-layout: fixed;
width: 100%; /* 固定寬度 */
}
td:first-child, th:first-child {
position:sticky;
left:0; /* 首行在左 */
z-index:1;
background-color:lightpink;
}
thead tr th {
position:sticky;
top:0; /* 第一列最上 */
}
th:first-child{
z-index:2;
background-color:lightblue;
}
</style>
</head>
<body>
<div class="test-table">
<table cellSpacing="0" cellPadding="0">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>爱好</th>
<th>语文</th>
<th>数学</th>
<th>英语</th>
<th>历史</th>
<th>地理</th>
<th>物理</th>
<th>化学</th>
<th>政治</th>
<th>体育</th>
</tr>
</thead>
<tbody>
<tr>
<td>wx001</td>
<td>张三</td>
<td>14</td>
<td>男</td>
<td>毛笔字</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx002</td>
<td>李四</td>
<td>14</td>
<td>男</td>
<td>跳舞</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx003</td>
<td>王五</td>
<td>14</td>
<td>男</td>
<td>音乐</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx004</td>
<td>何马</td>
<td>14</td>
<td>男</td>
<td>跳舞</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx005</td>
<td>谢谢</td>
<td>15</td>
<td>男</td>
<td>画画</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx006</td>
<td>李西</td>
<td>14</td>
<td>女</td>
<td>跳舞</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx007</td>
<td>照照</td>
<td>14</td>
<td>男</td>
<td>跳舞</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx008</td>
<td>阳阳</td>
<td>15</td>
<td>男</td>
<td>跳舞</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
<tr>
<td>wx009</td>
<td>浩浩</td>
<td>14</td>
<td>男</td>
<td>跳舞</td>
<td>92</td>
<td>99</td>
<td>90</td>
<td>94</td>
<td>91</td>
<td>90</td>
<td>95</td>
<td>90</td>
<td>100</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
2. 固定表头和列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.table {
display: table;
border-collapse: separate;
border-spacing: 0;
border-color: grey;
}
td {
padding: 4px;
/* border: 1px solid #e6e6e6; */
background: lightblue;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
}
.table-box{
position: relative;
padding: 0;
width: 710px;
background-color: rgb(255, 255, 255);
margin-bottom: 5px;
border: 1px solid gray;
margin: 0 auto;
}
.table-left-box {
overflow: hidden;
top: 0;
left: 0;
max-width: 90px;
z-index: 100
}
.table-right-box {
position: absolute;
overflow: hidden;
top: 0;
right: 0;
width: 621px;
}
.table-left-body td {
border-top: none;
background: lightpink;
}
.table-right-body td {
border-top: none;
background: #ffffff;
}
.table-left-body {
overflow-x: hidden;
overflow-y: hidden;
max-width: 90px;
max-height: 174px;
}
.table-left-body .table-left-text{
width: 80px;
height: 35px;
line-height: 35px;
}
.table-right-body {
overflow-x: auto;
overflow-y: auto;
width: 100%;
max-height: 174px;
}
.table-right-header{
width: 100%;
overflow-x: hidden;
overflow-y: hidden;
}
.table-right-text{
width: 160px;
height: 35px;
line-height: 35px;
}
</style>
</head>
<body>
<div class="table-box">
<div class="table-left-box">
<div class="table-left-header">
<div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="td color">
<div style="width: 80px;height: 35px;line-height: 35px;">
学号
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div ref="bodyWrapperLeft" class="table-left-body">
<div style="padding-bottom: 20px;box-sizing: border-box;">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div class="table-left-text">
wx001
</div>
</td>
</tr>
<tr>
<td>
<div class="table-left-text">
wx002
</div>
</td>
</tr>
<tr>
<td>
<div class="table-left-text">
wx003
</div>
</td>
</tr>
<tr>
<td>
<div class="table-left-text">
wx004
</div>
</td>
</tr>
<tr>
<td>
<div class="table-left-text">
wx005
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="table-right-box">
<div ref="headerWrapper" class="table-right-header">
<div style="width: 10000px;">
<table border="0" cellspacing="0" cellpadding="0" class="">
<tbody>
<tr>
<td>
<div class="table-right-text">
年龄
</div>
</td>
<td>
<div class="table-right-text">
性别
</div>
</td>
<td>
<div class="table-right-text">
爱好
</div>
</td>
<td>
<div class="table-right-text">
语文
</div>
</td>
<td>
<div class="table-right-text">
数学
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div ref="bodyWrapper" class="table-right-body">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div class="table-right-text">
14
</div>
</td>
<td>
<div class="table-right-text">
男
</div>
</td>
<td>
<div class="table-right-text">
毛笔字
</div>
</td>
<td>
<div class="table-right-text">
92
</div>
</td>
<td>
<div class="table-right-text">
99
</div>
</td>
</tr>
<tr>
<td>
<div class="table-right-text">
14
</div>
</td>
<td>
<div class="table-right-text">
男
</div>
</td>
<td>
<div class="table-right-text">
毛笔字
</div>
</td>
<td>
<div class="table-right-text">
92
</div>
</td>
<td>
<div class="table-right-text">
99
</div>
</td>
</tr>
<tr>
<td>
<div class="table-right-text">
14
</div>
</td>
<td>
<div class="table-right-text">
男
</div>
</td>
<td>
<div class="table-right-text">
毛笔字
</div>
</td>
<td>
<div class="table-right-text">
92
</div>
</td>
<td>
<div class="table-right-text">
99
</div>
</td>
</tr>
<tr>
<td>
<div class="table-right-text">
14
</div>
</td>
<td>
<div class="table-right-text">
男
</div>
</td>
<td>
<div class="table-right-text">
毛笔字
</div>
</td>
<td>
<div class="table-right-text">
92
</div>
</td>
<td>
<div class="table-right-text">
99
</div>
</td>
</tr>
<tr>
<td>
<div class="table-right-text">
14
</div>
</td>
<td>
<div class="table-right-text">
男
</div>
</td>
<td>
<div class="table-right-text">
毛笔字
</div>
</td>
<td>
<div class="table-right-text">
92
</div>
</td>
<td>
<div class="table-right-text">
99
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<script>
function $(select){
return document.querySelector(select)
}
let bodyWrapper = $('.table-right-body')
let bodyWrapperLeft = $('.table-left-body')
let headerWrapper = $('.table-right-header')
bodyWrapper.addEventListener('scroll', resetPosition, { passive: true });
function resetPosition() {
const {
scrollLeft, scrollTop, offsetWidth, scrollWidth
} = bodyWrapper;
if (bodyWrapperLeft) bodyWrapperLeft.scrollTop = scrollTop;
if (headerWrapper) headerWrapper.scrollLeft = scrollLeft;
}
</script>
</body>
</html>