以下记录是个人开发过程中遇到的问题:
当列表内容部分可见时,保持横向滚动条在下方。
实现
原理
1.这里涉及到两个Dom
元素,类名分别为 el-table__body-wrapper
、el-table__body
通过观察发现横向滚动条在于el-table__body-wrapper
上,el-table__body
则是实际的列表内容,当el-table__body
宽度超出el-table__body-wrapper
时就会出现横向滚动条。
2.因此只需要动态的修改el-table__body-wrapper
的height
即可实现想要的效果。
3.在页面发生滚动、页面大小改变以及数据源更新的时候对el-table__body-wrapper
的height
进行调整。
代码
这里是通过mixin方式的实现。
let el;
let tableBodyWrapDom = document.getElementsByClassName('.el-table__body-wrapper');
let tableBodyDom = document.getElementsByClassName('.el-table__body')
function handle() {
if (!el) return;
// top为dom上侧距离可视窗口顶部的值
const { top:tableBodyDomTop } = tableBodyWrapDom.getBoundingClientRect();
if (tableBodyDomTop > window.innerHeight || tableBodyWrapDom.classList.contains('is-scrolling-none')) {
// 此时列表在可视窗口的下侧不可见区域,因此不做任何修改
tableBodyWrapDom.style.height = 'unset'
tableBodyWrapDom.style.marginBottom = 'unset';
} else {
// 窗口高度 - 列表距顶部值 且 不超过自身实际值
let wrapHeight = Math.min(window.innerHeight - tableBodyDomTop, tableBodyDom.offsetHeight);
tableBodyWrapDom.style.height = wrapHeight + 'px';
// 需要用marginBottom填充,以保持列表原有高度,避免页面的纵向滚动条变化导致页面滚动的不流畅
// 可以通过注释这一行代码观察其效果差异
tableBodyWrapDom.style.marginBottom = (tableBodyDom.offsetHeight - wrapHeight) + 'px';
// console.log(tableBodyWrapDom.style.marginBottom,'marginBottom')
}
}
export default {
mounted() {
el = this.$el; // 当前组件的Dom对象,避免操作到本组件之外的Dom
tableBodyWrapDom = el.querySelector('.el-table__body-wrapper');
tableBodyDom = el.querySelector('.el-table__body');
// 监听事件
window.addEventListener('scroll', handle,true);
window.addEventListener('resize', handle,true);
},
destroyed() {
// 在组件销毁时取消监听
window.removeEventListener('scroll', handle,true);
window.removeEventListener('resize', handle,true);
},
watch: {
list() {
// 当列表数据源发生变化时,再次触发
this.$nextTick( handle);
}
}
}
watch中监听的list:在引用混合的组件中
<el-table
ref="brandTable"
:data="list" <----
style="width: 100%"
@selection-change="handleSelectionChange"
v-loading="listLoading"
border
>
....
</el-table>