Vue 监测 “指定容器“ 是否滚动到 “底部“ 和 “顶部“

文章介绍了如何在模块化项目(如Vue)中使用ScrollBoundary库来检测滚动边界,包括安装、导入、初始化和使用方法。非模块化项目可以通过创建ScrollBoundary.js文件并添加相关代码来实现。该库提供了一个Bus类和ScrollBoundary类,用于判断滚动是否达到容器的顶部或底部,并通过事件发布和订阅机制进行回调。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

废话少说直接看图:

使用方法(模块化项目,如Vue等):

1、npm install scrollboundary

2、import ScrollBoundary from 'scrollboundary'

3、let s = new ScrollBoundary(el)   el: 滚动的容器dom元素  默认不传是body (不需要设置高度和overflow: auto, 内置了)

(如果不是body元素, 建议设置固定高度,如果需要响应式高度,则需要calc计算成要固定的高度即可)
4、s.start(callback)  callback: 回调函数, 形参就是是否滚动到了边界


非模块化项目使用( 创建一个  ScrollBoundary.js   的文件, 并把下面代码粘贴进去 )

class Bus {
  constructor() {
    this.allEvent = Object.create(null)
  }

  // 发布
  on(eventType, handler) {
    this.allEvent[eventType] = this.allEvent[eventType] || []
    this.allEvent[eventType].push(handler)
  }

  // 订阅
  emit(eventType, ...args) {
    if(this.allEvent[eventType]){
      this.allEvent[eventType].forEach(handler => {
        handler(...args)
      })
    }
  }

  // 取消订阅
  off(eventType) {
    if(this.allEvent[eventType]) this.allEvent[eventType] = []
  }

  // 全部取消
  close(){
    this.allEvent = Object.create(null)
  }
}

// 判断是否滚动到最底部
class ScrollBoundary extends Bus {
  #el
  #top
  #height
  #lock = true
  #screenHeight = window.innerHeight
  #cb = () => {}
  // 节流
  #cut = (cb) => {
    if(this.#lock) {
      this.#lock = false
      setTimeout(() => {
        this.#lock = true
        cb()
      }, 60)
    }
  }

  // 私有处理是否到底触顶方法
  #topBottomFn = (e, init) => {
    let screen = this.#screenHeight - (this.#screenHeight - this.#height)
    // 判断思路 滚上去的距离 + 屏幕的高度 - (屏幕的高度 - 这个容器的高度)  == 滚动容器的高度    为到底部
    if(!init) {
      if(e.target.scrollTop + screen  == e.target.scrollHeight) this.emit('toBottom', { message: '已经到达指定容器的-->底部', to: 'bottom' })
      if(e.target.scrollTop == 0) this.emit('toBottom', { message: '已经到达指定容器的-->顶部', to: 'top' })
    }else{
      if(e.scrollTop + screen > e.scrollHeight) this.emit('toBottom', { message: '已经到达指定容器的-->底部', to: 'bottom' })
      if(e.scrollTop == 0) this.emit('toBottom', { message: '已经到达指定容器的-->顶部', to: 'top' })
    }
  }

  #noBody = (el) => {
    let fragment = document.createDocumentFragment('div')
    let div = document.createElement('div')
    div.classList.add('scroll-wrap-boundary')
    Array.from(el.children).forEach(item => {
      div.appendChild(item)
    })
    fragment.appendChild(div)
    document.body.appendChild(fragment)
    this.#el = div
  }

  constructor(el = document.body) {
    super()
    if(el.nodeName === 'BODY') this.#noBody(el)
    else this.#el = el
    getComputedStyle(this.#el).overflow == 'visible' ? this.#el.style.overflow = 'auto' : '' // 设置容器滚动否则不生效
    this.#top = el.getBoundingClientRect().top
    this.#height = el.getBoundingClientRect().height
  }

  start(cb) {
    let that = this
    this.#cb = cb
    this.on('toBottom', this.#cb)
    this.#topBottomFn(this.#el, 'init')
    this.#el.addEventListener('scroll', e => that.#cut(() => that.#topBottomFn(e)))
  }
}

1、引入这个文件 

2、

完了就.....ojbk了....如此...如此简单.....

最后最后!!!

还不快打开你的 vscode ???,快上车!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值