UNPKG

press-pix

Version:
82 lines (61 loc) 1.9 kB
import { useEffect, useRef, useCallback } from 'preact/hooks'; export const useLoadMore = (onReachBottom, options: { threshold?: number; debounceDelay?: number; isEnabled?: boolean; finished?: boolean; containerRef?: any; } = {}) => { const { threshold = 100, debounceDelay = 100, isEnabled = true, finished, containerRef: externalContainerRef, // 外部传入的容器ref } = options; const internalContainerRef = useRef(null); const containerRef = externalContainerRef || internalContainerRef; // 防抖函数 const debounce = useCallback((func, delay) => { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; }, []); // 触底判断 const checkIsBottom = useCallback((element) => { if (!element) return false; const { scrollTop, scrollHeight, clientHeight } = element; const scrollBottom = scrollHeight - scrollTop - clientHeight; return scrollBottom <= threshold; }, [threshold]); // 滚动处理 const handleScroll = useCallback( debounce(() => { if (!isEnabled || finished) return; // finished时不再触发 const container = containerRef.current; if (!container) return; if (checkIsBottom(container)) { onReachBottom(); } }, debounceDelay), [finished, debounceDelay, isEnabled, checkIsBottom, onReachBottom], ); // 事件监听 useEffect(() => { const container = containerRef.current; if (!container) return; if (!isEnabled) { container.removeEventListener('scroll', handleScroll); return; } container.addEventListener('scroll', handleScroll); return () => { container.removeEventListener('scroll', handleScroll); }; }, [handleScroll, isEnabled, containerRef]); return { containerRef, }; };