自动跟随滑动到容器底部,上滑停止跟随,再次滚动到底部触发自动跟随滚动底部
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) {
targetElement.value.scrollTop = targetElement.value.scrollHeight
}
}, 0)
}
onMounted(() => {
nextTick(() => {
scrollToBottom({ behavior: 'instant' })
})
})
onUnmounted(() => {
stopMutationObserver()
stopResizeObserver()
clearTimeout(timer)
})
return {
scrollToBottom,
arrivedState,
measure
}
}
参数
| 参数 | 说明 | 类型 | 默认值 |
|---|
| ref | DOM节点或者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 | () => {} |
使用说明
- useAutoScroll接收滚动容器,可以是DOM,也可以是Vue组件实例。
- 返回值scrollToBottom为滚动到底部方法,默认平滑滚动,业务方可以在滑动到其他地方的时候,通过调用该方法回到底部。
- arrivedState 与 vueuse useScroll API的arrivedState属性保持一致,可以通过监听arrivedState中的属性判断是否到达上下左右边界。默认上下偏移量为50px。
- measure 与 vueuse useScroll API的measure属性保持一致,可以在改变包裹容器属性的时候,重新计算滚动状态。