1. 功能目标
当用户向下滚动页面并进入明细数据表格区域时,表头固定在浏览器可视窗口顶部;当滚动位置离开表格区域或超过表格底部时,表头自动恢复到原位置。
- 解决 Element UI 表格原生结构下 CSS sticky 不稳定的问题。
- 只在视口顶部位于 el-table 范围内时固定表头。
- 固定表头时保持宽度、左侧位置与表格一致,避免列错位。
- 数据刷新、窗口尺寸变化时重新计算固定状态。
2. 实现总览
实现采用滚动事件 + DOM 边界判断 + fixed 样式切换。核心流程如下:
- mounted 中注册 resize 和 scroll 监听。
- getBiTableElements 获取表格、表头和表体 DOM。
- updateBiTableHeaderFixed 判断是否需要固定表头。
- resetBiTableHeaderFixed 在离开表格区域时清除固定状态。
- beforeDestroy 中解绑事件并清理固定样式。
3. 关键代码片段
滚动监听与生命周期清理
javascript
mounted() {
window.addEventListener('resize', this.resizeCharts);
window.addEventListener('scroll', this.updateBiTableHeaderFixed, true);
this.$nextTick(() => {
this.updateBiTableHeaderFixed();
});
},
beforeDestroy() {
window.removeEventListener('resize', this.resizeCharts);
window.removeEventListener('scroll', this.updateBiTableHeaderFixed, true);
this.resetBiTableHeaderFixed();
}
表格元素获取
javascript
getBiTableElements() {
const table = this.$el && this.$el.querySelector('.bi-table.el-table');
if (!table) {
return {};
}
return {
table,
header: table.querySelector('.el-table__header-wrapper'),
body: table.querySelector('.el-table__body-wrapper')
};
}
固定和释放判断
javascript
updateBiTableHeaderFixed() {
const { table, header, body } = this.getBiTableElements();
if (!table || !header || !body) {
return;
}
const tableRect = table.getBoundingClientRect();
const headerHeight = header.offsetHeight || 0;
const shouldFix = tableRect.top <= 0 && tableRect.bottom > headerHeight;
if (!shouldFix) {
this.resetBiTableHeaderFixed();
return;
}
header.classList.add('bi-table-header-fixed');
header.style.left = tableRect.left + 'px';
header.style.top = '0px';
header.style.width = tableRect.width + 'px';
body.style.paddingTop = headerHeight + 'px';
}
固定表头样式
css
.bi-page .bi-table .el-table__header-wrapper.bi-table-header-fixed {
position: fixed;
z-index: 2000;
overflow: hidden;
}