AI应用中自动跟随滑动到底部hook

176 阅读2分钟

自动跟随滑动到容器底部,上滑停止跟随,再次滚动到底部触发自动跟随滚动底部

vue3项目直接使用,该hook依赖vueuse实现

直接上代码

import { onMounted, onUnmounted, nextTick, computed } from 'vue'
import { useScroll, useMutationObserver, useResizeObserver, unrefElement } from '@vueuse/core'

export const useAutoScroll = (
  target,
  offset = {
    bottom: 50,
    top: 50,
    left: 0,
    right: 0
  }
) => {
  const autoScroll = () => {
    if (arrivedState.bottom) {
      scrollToBottom({ behavior: 'instant' })
    }
  }

  const { arrivedState, measure } = useScroll(target, { offset })

  const { stop: stopMutationObserver } = useMutationObserver(target, autoScroll, {
    childList: true, // 监听子节点的增删
    subtree: true, // 监听所有后代节点的变化
    attributes: true, // 监听属性变化
    characterData: true // 监听文本内容变化
  })

  const { stop: stopResizeObserver } = useResizeObserver(target, autoScroll)

  const targetElement = computed(() => {
    return unrefElement(target)
  })
  let timer = null
  // 滚动到底部
  const scrollToBottom = ({ behavior = 'smooth' } = {}) => {
    if (!targetElement.value) return

    // 保证同步添加的元素添加完成后再滚动
    timer = setTimeout(() => {
      try {
        targetElement.value.scrollTo({
          top: targetElement.value.scrollHeight,
          behavior
        })
      } catch (error) {
        // 降级处理:直接设置 scrollTop
        targetElement.value.scrollTop = targetElement.value.scrollHeight
      }
    }, 0)
  }

  onMounted(() => {
    nextTick(() => {
      scrollToBottom({ behavior: 'instant' })
    })
  })

  onUnmounted(() => {
    stopMutationObserver()
    stopResizeObserver()

    clearTimeout(timer)
  })

  return {
    scrollToBottom,
    arrivedState,
    measure
  }
}
参数
参数说明类型默认值
refDOM节点或者vue组件实例Element/ElementRef
offset包裹容器上下左右的偏移量object{top: 50, bottom: 50, right: 0, left: 0}
返回值
属性名说明类型
arrivedState响应式是否接触边框{ "left": true, "right": true, "top": false, "bottom": false }
scrollToBottom滚动到底部函数() => {}
measure手动更新滚动位置和 arrivedState() => {}

使用说明

  1. useAutoScroll接收滚动容器,可以是DOM,也可以是Vue组件实例。
  2. 返回值scrollToBottom为滚动到底部方法,默认平滑滚动,业务方可以在滑动到其他地方的时候,通过调用该方法回到底部。
  3. arrivedState 与 vueuse useScroll API的arrivedState属性保持一致,可以通过监听arrivedState中的属性判断是否到达上下左右边界。默认上下偏移量为50px。
  4. measure 与 vueuse useScroll API的measure属性保持一致,可以在改变包裹容器属性的时候,重新计算滚动状态。