让table固定表头并冻结列的一种简单实现方法

标题已经说明需求,就不说废话了,直接上code;)

.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!--把table放到div容器里。-->
<div class="table-container">
<table class="table-fixed">
<thead>
<tr>
<th class="col-fixed">fixed0</th>
<th>column0</th>
...省略其它th...
</tr>
</thead>
<tbody>
<tr>
<td class="col-fixed">fixed1</td>
<td>column1</td>
....省略其它td...
</tr>
....省略其它tr...
</tbody>
</table>
<div>

.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
/*限制容器宽高并允许滚动*/
.table-container{
width:100%;
max-height:200px;
overflow:auto;
}
/*表头cell设为相对定位*/
.table-fixed>thead>tr>th{
position:relative;
z-index:100;
background-color:#eee;
}
/*冻结列设为相对定位*/
.table-fixed>tbody>tr>td.col-fixed{
position:relative;
background-color:#eee;
}
/*设置z-index避免被覆盖*/
.table-fixed>thead>tr>th.col-fixed{
z-index:110;
}
</style>

.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
//需先引入jquery
$(function(){
var $table = $('.table-fixed');
var $topFixes = $table.find('thead>tr>th');
var $colFixes = $table.find('.col-fixed');
//容器滚动时,为实现fixed冻结效果:
//1、把表头cell的top设为scrollTop
//2、冻结列的left设为scrollLeft
$table.closest('.table-container').scroll(function(){
$topFixes.css('top',this.scrollTop);
$colFixes.css('left',this.scrollLeft);
});
});
</script>

##总结
相较于表头和内容分离的做法,这种实现方式不会出现对不齐的问题,而且比较简单(:不想写js的请忽略)

##已知问题

  1. 桌面Chrome下的效果最好,其他浏览器fixed内容有点闪烁。
  2. 移动端浏览器下的延迟比较严重,只能改为用多个table实现。
  3. 如果冻结列超出容器(.table-container)的范围,会导致水平滚动条滚不到头(无限滚动)。