import type { Ref } from 'vue' import { ref, onMounted, watch, onUnmounted } from 'vue' import { isWindow, isObject } from '@/utils/is' import { useThrottleFn } from '@vueuse/core' export function useScroll( refEl: Ref, options?: { wait?: number leading?: boolean trailing?: boolean } ) { const refX = ref(0) const refY = ref(0) let handler = () => { if (isWindow(refEl.value)) { refX.value = refEl.value.scrollX refY.value = refEl.value.scrollY } else if (refEl.value) { refX.value = (refEl.value as Element).scrollLeft refY.value = (refEl.value as Element).scrollTop } } if (isObject(options)) { let wait = 0 if (options.wait && options.wait > 0) { wait = options.wait Reflect.deleteProperty(options, 'wait') } handler = useThrottleFn(handler, wait) } let stopWatch: () => void onMounted(() => { stopWatch = watch( refEl, (el, prevEl, onCleanup) => { if (el) { el.addEventListener('scroll', handler) } else if (prevEl) { prevEl.removeEventListener('scroll', handler) } onCleanup(() => { refX.value = refY.value = 0 el && el.removeEventListener('scroll', handler) }) }, { immediate: true } ) }) onUnmounted(() => { refEl.value && refEl.value.removeEventListener('scroll', handler) }) function stop() { stopWatch && stopWatch() } return { refX, refY, stop } }