From 54c8449f7b92a1f1f969ede0370deec637bb8510 Mon Sep 17 00:00:00 2001 From: kkfluous Date: Wed, 1 Apr 2026 23:59:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=94=A8=20IntersectionObserver=20?= =?UTF-8?q?=E6=9B=BF=E4=BB=A3=20scroll=20=E4=BA=8B=E4=BB=B6=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=80=91=E5=B8=83=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit scroll 事件在某些布局下不触发,改用 IntersectionObserver 监听列表底部哨兵元素,进入视口时自动加载下一页,更可靠。 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/modules/mileage/MonitoringView.tsx | 35 +++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/modules/mileage/MonitoringView.tsx b/src/modules/mileage/MonitoringView.tsx index eb6d780..8912048 100644 --- a/src/modules/mileage/MonitoringView.tsx +++ b/src/modules/mileage/MonitoringView.tsx @@ -115,8 +115,6 @@ export default function MonitoringView() { const [loadingMore, setLoadingMore] = useState(false); const [showBackToTop, setShowBackToTop] = useState(false); const PAGE_SIZE = 50; - const listEndRef = useRef(null); - const scrollContainerRef = useRef(null); const departments = filterOptions.departments; const plateNumbers = filterOptions.plates; @@ -178,26 +176,34 @@ export default function MonitoringView() { loadFirstPage(); }, [loadFirstPage]); - // 滚动触底检测 + 回到顶部按钮 + // 触底检测:用 IntersectionObserver 监听哨兵元素 const loadMoreRef = useRef(loadMore); loadMoreRef.current = loadMore; + const sentinelRef = useRef(null); + useEffect(() => { + const sentinel = sentinelRef.current; + if (!sentinel) return; + const observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting) { + loadMoreRef.current(); + } + }, + { rootMargin: '200px' } + ); + observer.observe(sentinel); + return () => observer.disconnect(); + }, []); + + // 回到顶部按钮 useEffect(() => { const handleScroll = () => { const scrollY = window.scrollY || document.documentElement.scrollTop; setShowBackToTop(scrollY > 400); - const scrollHeight = document.documentElement.scrollHeight; - const clientHeight = window.innerHeight; - if (scrollHeight - scrollY - clientHeight < 300) { - loadMoreRef.current(); - } }; window.addEventListener('scroll', handleScroll, { passive: true }); - document.addEventListener('scroll', handleScroll, { passive: true }); - return () => { - window.removeEventListener('scroll', handleScroll); - document.removeEventListener('scroll', handleScroll); - }; + return () => window.removeEventListener('scroll', handleScroll); }, []); const scrollToTop = () => { @@ -802,7 +808,8 @@ export default function MonitoringView() { 已加载全部 {total} 条 )} -
+ {/* 哨兵元素:进入视口时触发加载更多 */} +
{/* 回到顶部按钮 */}