控制表格向上滚动距离最佳实践(以Element ui为例)

前言

在web开发中,有些时候使用的组件库的表格不支持滚动的属性或方法。这个时候我们就要自己去实现这一功能。在Element Plus里,组件库已经具备了支持滚动表格的属性或方法,但是在支持vue2的element ui里,Table组件本身不提供直接控制滚动距离的属性或方法。我们接下来就以element ui为例,实现表格滚动,以提供给大家实现类似功能的一些思路。

实现思路

1.我们首先需要获取表格距离浏览器顶部的高度

2.我们需要获取滚动到的指定行到浏览器顶部的高度

3.用滚动到的指定行到浏览器顶部的高度减去格距离浏览器顶部的高度获取需要滚动的高度

4.对DOM的API,scrollTop进行赋值,滚动到指定位置

Tips:借助DOM的API,getBoundingClientRect来获取指定dom到浏览器顶部的高度

核心代码

// 滚动表格
scrollTable(index = 0) {
  const tableBodyWrapper = this.$refs.dataFilterTable.bodyWrapper;
  tableBodyWrapper.scrollTop = 0;
  const tableItems = document.getElementsByClassName('el-table__row')
  const tableTop = tableBodyWrapper.getBoundingClientRect().top 
  const tableItemTop = tableItems[index].getBoundingClientRect().top
  const scrollTop = tableItemTop - tableTop

  if (tableBodyWrapper) {
    //表格滚动
    tableBodyWrapper.scrollTop = scrollTop
  }
},

 完整代码示例

<template>
  <div>
    <div class="flex mb10 justify-end">
      <el-input-number v-model="line" class="mr10" :min="1" />
      <el-button type="primary" @click="scrollTable">滚动到第{{ line }}行</el-button>
    </div>
    <el-table ref="elTable" :data="tableData" border style="width: 100%" :height="tableHeight">
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="date" label="日期" width="180" />
      <el-table-column prop="name" label="姓名" width="180" />
      <el-table-column prop="address" label="地址" />
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      line: 1,
      tableHeight: 580,
      tableData: []
    }
  },
  created() {
    this.getData()
  },
  mounted() {
    window.addEventListener('resize', this.getNewTableHeight)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.getNewTableHeight)
  },
  methods: {
    scrollTable() {
      if (this.line > this.tableData.length) return this.$message.warning('超出数据范围')

      const tableBodyWrapper = this.$refs.elTable.bodyWrapper;
      tableBodyWrapper.scrollTop = 0;
      const tableItems = document.getElementsByClassName('el-table__row')
      const tableTop = tableBodyWrapper.getBoundingClientRect().top 
      const tableItemTop = tableItems[this.line - 1].getBoundingClientRect().top
      const scrollTop = tableItemTop - tableTop

      if (tableBodyWrapper) {
        //表格滚动
        tableBodyWrapper.scrollTop = scrollTop
      }
    },
    getNewTableHeight() {
      this.tableHeight = document.documentElement.clientHeight / (695 / 580)
    },
    getData() {
      const newTableData = []
      for (let index = 0; index < 100; index++) {
        let address = ''
        if (index % 2 === 0) {
          address = '上海市普陀区金沙江路 1518 弄'
        } else {
          address =
            '上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄上海市普陀区金沙江路 1517 弄'
        }
        newTableData.push({
          id: index + 1,
          date: '2016-05-02',
          name: '王小虎',
          address
        })
      }
      this.tableData = newTableData
    }
  }
}
</script>

<style lang="scss" scoped>
.flex {
  display: flex;
}
.justify-end {
  justify-content: flex-end;
}

.mr10 {
  margin-right: 10px;
}

.mb10 {
  margin-bottom: 10px;
}
</style>

效果展示

拓展 

getBoundingClientRect是什么?

getBoundingClientRect 是一个 DOM 方法,用于返回元素的大小及其相对于视口(viewport)的位置。它提供了非常详细的布局信息,包括元素的 top、right、bottom 和 left 边缘的位置,以及宽度和高度等属性。

返回值

getBoundingClientRect 返回一个 DOMRect 对象,该对象包含以下属性:

  • top:元素上边缘相对于视口顶部的距离。
  • right:元素右边缘相对于视口左侧的距离。
  • bottom:元素下边缘相对于视口顶部的距离。
  • left:元素左边缘相对于视口左侧的距离。
  • width:元素的宽度(等于 right - left)。
  • height:元素的高度(等于 bottom - top)。
  • x:等同于 left
  • y:等同于 top

使用场景

getBoundingClientRect 在许多场景中都非常有用,例如:

  • 检测元素是否在视口中可见:通过比较 top 和 bottom 与视口的高度,可以判断元素是否完全或部分可见。
  • 实现滚动效果:根据元素的位置动态调整滚动行为。
  • 定位绝对或固定位置的元素:确保这些元素相对于其他元素或视口正确对齐。
  • 碰撞检测:在游戏中或交互式应用中检测两个元素是否重叠。

 注意事项

  • 视口依赖性getBoundingClientRect 返回的坐标是相对于视口的,而不是相对于整个文档。如果你需要相对于文档的坐标,可以使用 element.offsetLeft 和 element.offsetTop,或者将视口坐标转换为文档坐标。
  • 滚动条影响:如果页面有滚动条,getBoundingClientRect 的结果会受到滚动条的影响。你可以结合 window.scrollX 和 window.scrollY 来获取相对于整个文档的坐标。
  • 性能考虑:频繁调用 getBoundingClientRect 可能会影响性能,因为它会触发浏览器重新计算布局(reflow)。因此,在性能敏感的应用中,应该尽量减少调用次数。

动态更新 

由于 getBoundingClientRect 返回的结果是基于当前布局状态的,因此当窗口大小改变、滚动或者元素样式发生变化时,你可能需要重新调用此方法以获取最新的布局信息。

总之,getBoundingClientRect 是一个非常强大的工具,可以帮助开发者精确地了解页面元素的布局信息。通过合理使用,可以实现更加复杂和精细的前端交互效果。

scrollTop是什么?

scrollTop 是一个用于获取或设置元素滚动条垂直位置的属性。它在处理页面或元素的滚动行为时非常有用。以下是关于 scrollTop 的详细说明:

获取和设置

  • 获取scrollTop 可以用来获取某个元素内部滚动条的垂直位置,即滚动了多少像素。
  • 设置:你也可以通过设置 scrollTop 来改变元素内部滚动条的位置。

属性值

  • 返回值:当作为获取器使用时,scrollTop 返回一个整数,表示从元素顶部到视口顶部的距离(单位为像素)。
  • 设置值:当作为设置器使用时,scrollTop 接受一个整数值,表示要滚动到的目标位置(单位为像素)。

适用元素

  • document.documentElement 或 document.body:对于整个页面的滚动,可以使用 document.documentElement.scrollTop 或 document.body.scrollTop。需要注意的是,在不同的浏览器中,这两个属性的行为可能有所不同。现代浏览器通常推荐使用 document.documentElement.scrollTop
  • 任何具有滚动条的元素:如 divsection 等设置了 overflow: auto 或 overflow: scroll 的块级元素。

scrollTop 是一个非常有用的属性,可以帮助开发者精确地控制和获取元素的滚动状态。通过合理使用,可以实现更加复杂和精细的滚动效果和交互体验。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零凌林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值