侧边栏壁纸
博主头像
M酷博主等级

一帆风顺 ⛵️⛵️⛵️

  • 累计撰写 42 篇文章
  • 累计创建 37 个标签
  • 累计收到 351 条评论

目 录CONTENT

文章目录

el-table滚动条保持在可见范围内

M酷
2021-06-16 / 0 评论 / 0 点赞 / 570 阅读 / 2,292 字 / 正在检测是否收录...

实现效果

stickPicture.png

原理

这里涉及到2个Dom元素,类名分别为 el-table__body-wrapper、el-table__body。

通过观察发现横向滚动条在于el-table__body-wrapper上,el-table__body则是实际的列表内容,当el-table__body宽度超出el-table__body-wrapper时就会出现横向滚动条。

因此只需要动态的修改 el-table__body-wrapper 的 height 即可实现想要的效果。
在页面发生滚动、页面大小改变以及数据源更新的时候对 el-table__body-wrapper 的 height 进行调整。

代码及使用

我们直接通过mixin混入相关代码来实现复用。
以下为 table-scroller.js

let el
let tableBodyWrapDom
let tableBodyDom
let scrollContainer
export default {
  destroyed() {
    // 在组件销毁时取消监听
    scrollContainer.removeEventListener('scroll', this.handleScroll)
    window.removeEventListener('resize', this.handleScroll)
  },
  methods: {
    async initScroll(scrollEl = 'body') {
      await this.$nextTick()
      el = this.$el // 当前组件的Dom对象,避免操作到本组件之外的Dom
      tableBodyWrapDom = el.querySelector('.el-table__body-wrapper')
      tableBodyDom = el.querySelector('.el-table__body')
      scrollContainer = document.querySelector(scrollEl) // 滚动的容器,默认为body
      // this.$refs.table.handleFixedMousewheel = function() {} // 消除 FixedMousewheel 带来的问题
      // 监听事件
      scrollContainer.addEventListener('scroll', this.handleScroll, false)
      window.addEventListener('resize', this.handleScroll, false)
    },
    handleScroll() {
      if (!el || !tableBodyWrapDom) 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 {
        // 窗口高度 - 列表距顶部值 且 不超过自身实际值
        const wrapHeight = Math.min(window.innerHeight - tableBodyDomTop, tableBodyDom.offsetHeight)
        tableBodyWrapDom.style.height = wrapHeight + 'px'
        // 需要用marginBottom填充,以保持列表原有高度,避免页面的纵向滚动条变化导致页面滚动的不流畅
        // 可以通过注释这一行代码观察其效果差异
        tableBodyWrapDom.style.marginBottom = (tableBodyDom.offsetHeight - wrapHeight) + 'px'
      }
    }
  },
  watch: {
    tableData(n) {
      // 当列表数据源发生变化时,再次触发
      n.length && this.$nextTick(this.handleScroll)
    }
  }
}

使用时,只需要引入mixin,然后再合适的地方,执行 initScroller 即可

import tableScroller from '@/mixins/table-scroller'
export default {
    mixins: [tableScroller],
    methods: {
        getDate() {
            ...
            this.initScroll('.main-container'); // 传入滚动容器的class或id        
        }    
    }
}
0
广告 广告

评论区