diff --git a/src/components/InfiniteScroll/index.jsx b/src/components/InfiniteScroll/index.jsx index ac53dd3..bb6d62e 100644 --- a/src/components/InfiniteScroll/index.jsx +++ b/src/components/InfiniteScroll/index.jsx @@ -6,41 +6,61 @@ const InfiniteScroll = ({ loadMore, hasMore, children, - threshold = 50, + threshold = 0.1, // 触发阈值,元素可见比例 className = "", empty = false, }) => { const containerRef = useRef(null); + const sentinelRef = useRef(null); + const observerRef = useRef(null); const [loading, setLoading] = useState(false); + const [hasInitialized, setHasInitialized] = useState(false); // 首次挂载 + + // 加载更多数据的处理函数 + const handleLoadMore = () => { + if (loading || !hasMore) return; - const handleScroll = () => { - if (loading) return; setLoading(true); - if (!containerRef.current || !hasMore) return; - - const { scrollTop, scrollHeight, clientHeight } = containerRef.current; - - if (scrollTop + clientHeight >= scrollHeight - threshold) { - loadMore().finally(() => { - setLoading(false); - }); - } + loadMore().finally(() => { + setLoading(false); + }); }; + // 设置IntersectionObserver useEffect(() => { - const container = containerRef.current; - if (container) { - container.addEventListener("scroll", handleScroll); - // 初始加载时检查是否需要加载更多 - handleScroll(); + // 初始化观察器 + const options = { + root: containerRef.current, + rootMargin: "0px 0px 50px 0px", // 减少提前触发距离 + threshold, + }; + + // 创建观察器实例 + observerRef.current = new IntersectionObserver((entries) => { + const [entry] = entries; + if (entry.isIntersecting) { + handleLoadMore(); + } + }, options); + + // 开始观察哨兵元素 + if (sentinelRef.current) { + observerRef.current.observe(sentinelRef.current); } + // 初始加载检查 - 仅在组件首次挂载时执行 + if (hasMore && !loading && !hasInitialized) { + setHasInitialized(true); + handleLoadMore(); + } + + // 清理函数 return () => { - if (container) { - container.removeEventListener("scroll", handleScroll); + if (observerRef.current) { + observerRef.current.disconnect(); } }; - }, [loadMore, hasMore, threshold]); + }, [loadMore, hasMore, threshold, loading]); return (
加载中...