From 98a18a5d7f619f147d37a27039a1992760b73374 Mon Sep 17 00:00:00 2001 From: JSR Date: Wed, 18 Mar 2026 18:43:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=AD=97=E6=AF=8D=E6=B0=B4?= =?UTF-8?q?=E6=BB=B4=E6=96=B9=E5=90=91=E5=B9=B6=E5=A2=9E=E5=8A=A0=E6=9C=AA?= =?UTF-8?q?=E6=8C=89=E4=B8=8B=E6=97=B6=E7=9A=84=E6=B5=85=E8=93=9D=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E6=8C=87=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Home.tsx | 91 ++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/src/components/Home.tsx b/src/components/Home.tsx index 749b6f2..3d22475 100644 --- a/src/components/Home.tsx +++ b/src/components/Home.tsx @@ -430,22 +430,21 @@ export const Home: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { const bodyWebkitUserSelectRef = useRef("") const [navActiveKey, setNavActiveKey] = useState(null) const [navIndicatorY, setNavIndicatorY] = useState(0) - const [navIndicatorVisible, setNavIndicatorVisible] = useState(false) + const [isNavDraggingState, setIsNavDraggingState] = useState(false) const setNavDraggingState = useCallback((dragging: boolean) => { isNavDragging.current = dragging + setIsNavDraggingState(dragging) if (dragging) { bodyUserSelectRef.current = document.body.style.userSelect bodyWebkitUserSelectRef.current = document.body.style.webkitUserSelect document.body.style.userSelect = "none" document.body.style.webkitUserSelect = "none" - setNavIndicatorVisible(true) return } document.body.style.userSelect = bodyUserSelectRef.current document.body.style.webkitUserSelect = bodyWebkitUserSelectRef.current - setNavIndicatorVisible(false) }, []) const handleNavAction = useCallback( @@ -520,6 +519,45 @@ export const Home: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { } }, []) + useEffect(() => { + if (!groupedStudents.length) { + setNavActiveKey(null) + return + } + + const refreshActiveByScroll = () => { + let currentKey = groupedStudents[0]?.key || null + const anchorY = 140 + + groupedStudents.forEach((group) => { + const el = groupRefs.current[group.key] + if (!el) return + const top = el.getBoundingClientRect().top + if (top <= anchorY) { + currentKey = group.key + } + }) + + if (currentKey) { + setNavActiveKey(currentKey) + const idx = groupedStudents.findIndex((g) => g.key === currentKey) + if (idx >= 0 && navContainerRef.current) { + const rect = navContainerRef.current.getBoundingClientRect() + const itemHeight = rect.height / groupedStudents.length + setNavIndicatorY((idx + 0.5) * itemHeight) + } + } + } + + refreshActiveByScroll() + window.addEventListener("scroll", refreshActiveByScroll, { passive: true }) + window.addEventListener("resize", refreshActiveByScroll) + return () => { + window.removeEventListener("scroll", refreshActiveByScroll) + window.removeEventListener("resize", refreshActiveByScroll) + } + }, [groupedStudents]) + const renderQuickNav = () => { if ( groupedStudents.length <= 1 || @@ -555,18 +593,23 @@ export const Home: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { touchAction: "none", }} > - {navIndicatorVisible && navActiveKey && ( + {navActiveKey && (
= ({ canEdit }) => { zIndex: 2, }} > +
@@ -599,13 +656,17 @@ export const Home: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { fontSize: "11px", fontWeight: "bold", color: - navIndicatorVisible && navActiveKey === group.key - ? "#ffffff" + navActiveKey === group.key + ? isNavDraggingState + ? "#ffffff" + : "var(--ant-color-primary, #1890ff)" : "var(--ant-color-primary, #1890ff)", borderRadius: "50%", backgroundColor: - navIndicatorVisible && navActiveKey === group.key - ? "var(--ant-color-primary, #1890ff)" + navActiveKey === group.key + ? isNavDraggingState + ? "var(--ant-color-primary, #1890ff)" + : "rgba(24, 144, 255, 0.36)" : "transparent", pointerEvents: "none", }}