使用elTable组件 实现表格的无限无缝滚动
<el-table
ref="materialTable"
:data="materialData"
height="190"
style="margin-top: 5px"
@mouseenter.native="handleMaterialTableMouseEnter"
@mouseleave.native="handleMaterialTableMouseLeave"
>
<el-table-column prop="firClassName" label="一级名称" align="center" show-overflow-tooltip min-width="180px"></el-table-column>
<el-table-column prop="secClassName" label="二级名称" align="center" show-overflow-tooltip min-width="140px"></el-table-column>
<el-table-column prop="receiveRate" label="收料完成率" :formatter="(_, _2, cellValue) => cellValue + '%'" align="center" sortable></el-table-column>
</el-table>
private materialAutoScrollTimer: number | null = null
private isMaterialScrolling = true
private materialAnimationFrameId: number | null = null
// 获取滚动容器(提取公共方法)
private getMaterialScrollWrapper () {
return this.$refs.materialTable?.$el.querySelector('.el-table__body-wrapper')
}
// 鼠标移入表格时停止自动滚动
handleMaterialTableMouseEnter () {
this.stopMaterialAutoScroll()
this.removeMaterialTableBody()
}
// 鼠标移出表格时开始自动滚动
handleMaterialTableMouseLeave () {
this.startMaterialAutoScroll()
}
// 克隆表格体
cloneMaterialTableBody () {
const wrapper = this.getMaterialScrollWrapper()
if (wrapper) {
const tableBody = wrapper.querySelector('tbody')
if (tableBody && !tableBody.nextElementSibling) {
// 避免重复克隆
const cloneBody = tableBody.cloneNode(true) as HTMLElement
tableBody.parentNode.appendChild(cloneBody)
}
}
}
// 移除克隆的表格体
removeMaterialTableBody () {
const wrapper = this.getMaterialScrollWrapper()
if (wrapper) {
const tableBody = wrapper.querySelector('tbody')
if (tableBody && tableBody.nextElementSibling) {
tableBody.parentNode.removeChild(tableBody.nextElementSibling)
}
}
}
// 新增自动滚动方法
startMaterialAutoScroll () {
this.stopMaterialAutoScroll()
const wrapper = this.getMaterialScrollWrapper()
if (wrapper && wrapper.scrollHeight > wrapper.clientHeight) {
wrapper.classList.add('no-scroll')
this.cloneMaterialTableBody()
this.isMaterialScrolling = true
// 获取原始表格高度
const originalHeight = wrapper.scrollHeight / 2
const animate = () => {
if (!this.isMaterialScrolling || !wrapper) return
const { scrollTop } = wrapper
const newScrollTop = scrollTop + 0.8
// 当滚动超过原始高度时无缝重置
if (newScrollTop >= originalHeight) {
wrapper.scrollTop = newScrollTop - originalHeight
} else {
wrapper.scrollTop = newScrollTop
}
this.materialAnimationFrameId = requestAnimationFrame(animate)
}
this.materialAnimationFrameId = requestAnimationFrame(animate)
}
}
// 停止自动滚动方法
stopMaterialAutoScroll () {
const wrapper = this.getMaterialScrollWrapper()
if (wrapper) wrapper.classList.remove('no-scroll')
this.isMaterialScrolling = false
if (this.materialAnimationFrameId) {
cancelAnimationFrame(this.materialAnimationFrameId)
this.materialAnimationFrameId = null
}
if (this.materialAutoScrollTimer) {
clearInterval(this.materialAutoScrollTimer)
this.materialAutoScrollTimer = null
}
}
::v-deep .no-scroll {
overflow: hidden !important;
}