需求:
1、当表格数据未查看到最后一条时,分页固定在页面最下方,直到查看表格最后一行,分页取消固定; 2、当表格滑动到上方,表头固定在系统的上方
思路:
1、当鼠标滑动时判断表格距离浏览器上方的距离,当距离小于系统头部时,表头固定,反之取消固定, 可以使用@wheel获取滑轮滚动事件,也可以使用window.addEventListener监听滑动条滑动事件scroll 2、表头固定的方式有三种:
- 方法一:给el-table的height赋值,获取表格中滚动条滚动到最后一行,始终差着点值,不知道什么原因,考虑不周,想加占位符试试,最初实现了,但是因为高度固定,后面的占位符一直可视,所以冲突了,所以使用了方法二
- 方法二:使用一模一样的表格,把原表格的表头隐藏,把新表格的内容隐藏
- 方法三:自己使用div照着表头的样式写一个,个人不太喜欢这种
3、新增一个占位符在表格的下方,当该元素不在可视区域时,分页固定,反之,取消固定
反思:
1、@wheel获取滑轮滚动事件先触发,获取不到滚动条滑动的正确距离,所以有延迟 2、 固定表格时,由于考虑不周,忘记了固定了表格高度元素就一直可变了,想用方法一和方法二结合做, 3、改着改着代码手滑把判断表格距离浏览器上方的距离 <= 系统头部,写成了>头部
自己修改封装的分页组件Pagination.vue
<template>
<div :class= "{ 'fixed-foot': isFixed, 'pagination': !isFixed }">
<el-pagination
v-if="isSmall"
small
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, prev, pager, next"
:page-size="page.pageSize"
:total="page.total">
</el-pagination>
<el-pagination
:page-sizes="[10, 50, 100,500]"
layout="total,sizes,prev, pager, next,jumper"
:total="page.total"
:page-size="page.pageSize"
:current-page="page.currentPage"
@current-change="handleCurrentChange"
@size-change="handleSizeChange">
</el-pagination>
</div>
</template>
<script>
export default {
name: 'pagination',
props: {
page: {
type: Object,
default: {}
},
enableSmall: {
type: Boolean,
default: false,
},
isFixed: {
type: Boolean,
default: true,
}
},
data() {
return {
isSmall: this.enableSmall || false,
}
},
methods: {
handleCurrentChange(val){
this.$emit('pageChange', val);
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
this.$emit('pageChangeSize', val);
}
}
}
</script>
<style lang="less" scoped>
.pagination{
position: absolute;
bottom: 52px;
width: calc(100% - 216px);
margin: 0 !important;
text-align: right;
.el-pagination{
padding: 10px 10px 10px 0 !important;
background-color: rgba(99, 99, 99, 0.6);
}
}
.fixed-foot{
position: fixed;
width: calc(100% - 216px);
right: 10px;
bottom: 0;
margin: 0 !important;
text-align: right;
.el-pagination{
padding: 10px 10px 10px 0 !important;
background-color: rgba(99, 99, 99, 0.6);
}
}
/deep/.el-pagination__total{
color: #fff;
}
/deep/ .el-input__inner,
/deep/ .btn-prev,
/deep/ .btn-next,
/deep/ .el-pager li{
border: 1px solid transparent;
background-color: rgba(99, 99, 99, 0.6);
color: #fff;
}
/deep/ .el-pager li.active{
color: #409EFF;
}
/deep/ .el-pagination button:disabled{
background-color: rgba(99, 99, 99, 0.6);
}
/deep/ .el-pagination__jump{
color: #fff;
}
</style>
主要实现代码test.vue
<template>
<div class="mainbox" ref="scorll_top">
<el-table :data="emptyData" class="table-head" v-if="isFixedHead">
<el-table-column prop="NO" type="index" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="a" label="1"></el-table-column>
<el-table-column prop="b" label="2"></el-table-column>
<el-table-column prop="c" label="3"></el-table-column>
<el-table-column prop="d" label="4"></el-table-column>
<el-table-column prop="e" label="5"></el-table-column>
<el-table-column prop="f" label="6"></el-table-column>
</el-table>
<el-table id="alarmTable" :data="tableData" border stripe class="timeline-table">
<el-table-column prop="NO" type="index" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="a" label="1"></el-table-column>
<el-table-column prop="b" label="2"></el-table-column>
<el-table-column prop="c" label="3"></el-table-column>
<el-table-column prop="d" label="4"></el-table-column>
<el-table-column prop="e" label="5"></el-table-column>
<el-table-column prop="f" label="6"></el-table-column>
</el-table>
<Pagination ref="pagination" :page="page" :isFixed="isFixedFoot" @pageChange="pageChange" @pageChangeSize="pageChangeSize" v-if="page.total > 10"></Pagination>
<div class="placeholder" id="placeholder"></div>
</div>
</template>
<script>
export default {
name: "test",
components: {
Pagination: () => import('@components/common/Pagination')
},
data() {
return {
page:{
currentPage: 1,
pageSize: this.global.pageSize,
total: 0,
},
tableData: [],
isFixedFoot: true,
isFixedHead: null,
emptyData: []
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll, true)
},
methods: {
placeholderVisible(){
let rect = document.getElementById('placeholder').getBoundingClientRect()
const viewHeight = window.innerHeight || document.documentElement.clientHeight
console.log('判断', rect.bottom, window.innerHeight)
if(rect.bottom <= viewHeight){
console.log('元素出现')
this.isFixedFoot = false
}else{
console.log('元素消失')
this.isFixedFoot = true
}
},
handleScroll() {
let table = document.getElementById('table')
let offsetTop = this.$refs.scorll_top.getBoundingClientRect().top + Number(table.offsetTop-100)
if(offsetTop <= 100){
console.log('固定')
this.isFixedHead = true
}else{
console.log('移除固定')
this.isFixedHead = false
}
this.placeholderVisible()
},
loadTable(){
},
pageChange(val){
this.page.currentPage = val
this.loadTable()
},
pageChangeSize(val){
this.page.pageSize = val
this.global.pageSize = val
this.loadTable()
}
},
}
</script>
<style lang="less" scoped>
.mainbox{
width: calc(100% - 10px);
.table-head{
position: fixed;
top: 100px;
z-index: 1;
width: calc(100% - 216px);
/deep/ .el-table__header {
background-color: rgba(26, 64, 139, 0.9);
}
/deep/ .el-table__row,
/deep/ .el-table__empty-block{
display: none;
}
}
.placeholder{
min-height: 100px;
}
}
</style>
效果图如下,文字部分已打码 部分作废代码也记录一下吧,没准以后用的到
let dom = document.querySelector('.el-table__body-wrapper')
dom.addEventListener("scroll", () => {
const scrollDistance = dom.scrollHeight - dom.scrollTop - dom.clientHeight;
if (scrollDistance <= 1) {
console.log('已经见底了')
this.fixedFoot = false
this.isFixed = false
}else{
this.isFixed = true
}
})
let scrollTop = this.$refs.table.bodyWrapper.scrollTop
let scrollHeight = this.$refs.table.bodyWrapper.scrollHeight
console.log('差值', scrollHeight, scrollTop, scrollHeight - scrollTop)
this.$refs.table.bodyWrapper.scrollTop =this.$refs.table.bodyWrapper.scrollHeight;
let scrollHeight = this.$refs.table.bodyWrapper.scrollHeight
this.$refs.table.bodyWrapper.scrollTop = scrollHeight
if(scrollHeight - scrollTop <= 605){
}
let placeholder = document.getElementById('placeholder')
if(document.documentElement.contains(placeholder)){
console.log('滑动到底部')
}
主要参考文章: JS判断元素是否在可视区域 vue 中 elementUI el-table 实现滚动加载 关于scroll事件与wheel事件的区别
|