From 822af87855f8cf268a70b84536a27d235bdfea5c Mon Sep 17 00:00:00 2001 From: amypeng Date: Wed, 10 Jun 2026 08:45:09 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E9=A1=B5=E6=96=B0=E9=97=BB=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 首页新闻滚动 --- .../Pages/homepage/component/newsByNSCC.jsx | 116 +++++++++++++++--- .../Information/Pages/homepage/index.scss | 27 +--- 2 files changed, 105 insertions(+), 38 deletions(-) diff --git a/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx b/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx index 957b58c00..d6d053c9e 100644 --- a/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx +++ b/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx @@ -19,6 +19,11 @@ function News(props) { const [activeDirId, setActiveDirId] = useState(undefined); const [total, setTotal] = useState(0); const newsSectionRef = useRef(null); + const topBoxRef = useRef(null); + const [hasAppended, setHasAppended] = useState(false); + const [activeIndex, setActiveIndex] = useState(0); + const scrollIndexRef = useRef(0); + const scrollTimerRef = useRef(null); useEffect(() => { let hasAnimated = false; // 标记动画是否已触发 @@ -61,7 +66,7 @@ function News(props) { setDocListByFirstDir(data) }) - getPointsDoc(rows[1].id); + getPointsDoc(); } }) }, [id]) @@ -72,8 +77,82 @@ function News(props) { }, (data)=>{setTotal(data)}) }, [activeDirId]) - async function getPointsDoc(rowId) { - let res = await + // 监控topBox高度,当高度>593时复制docListBySecondDir追加到自身 + useEffect(() => { + if (!topBoxRef.current || !docListBySecondDir.length) return; + + const observer = new ResizeObserver((entries) => { + for (const entry of entries) { + const height = entry.contentRect.height; + if (height > 593 && !hasAppended) { + setDocListBySecondDir(prev => [...prev, ...docListBySecondDir]); + setHasAppended(true); + // 滚动动画由hasAppended变化触发的useEffect自动启动 + } + } + }); + + observer.observe(topBoxRef.current); + + return () => { + observer.disconnect(); + }; + }, [docListBySecondDir, hasAppended]) + + // 滚动动画:每隔3秒将下一个docBySecondDir_NSCC元素滚动到topBox顶部 + useEffect(() => { + if (!hasAppended || !topBoxRef.current) return; + + const topBox = topBoxRef.current; + scrollIndexRef.current = 0; + // 给topBox添加transition实现平滑动画 + topBox.style.transition = 'transform 0.5s linear'; + + scrollTimerRef.current = setInterval(() => { + const items = topBox.querySelectorAll('.docBySecondDir_NSCC'); + if (!items.length) return; + + const targetIndex = scrollIndexRef.current % items.length; + + // 计算目标元素之前所有元素的总高度(含margin),作为translateY偏移量 + let offset = 0; + for (let i = 0; i < targetIndex; i++) { + offset += items[i].offsetHeight; + const styles = window.getComputedStyle(items[i]); + offset += parseFloat(styles.marginBottom) || 0; + } + topBox.style.transform = `translateY(-${offset}px)`; + + // 滚动到第一个复制元素时,等待动画完成后瞬间重置offset为0,实现无缝循环 + if (targetIndex === docListBySecondDir.length / 2) { + setActiveIndex((targetIndex + 1) % (docListBySecondDir.length / 2)); + setTimeout(() => { + topBox.style.transition = 'none'; + topBox.style.transform = 'translateY(0)'; + void topBox.offsetWidth; + topBox.style.transition = 'transform 0.5s linear'; + setActiveIndex(1); + }, 500); + scrollIndexRef.current = 0; + } else { + setActiveIndex((targetIndex + 1) % (docListBySecondDir.length / 2)); + } + + scrollIndexRef.current++; + }, 3000); + + return () => { + if (scrollTimerRef.current) { + clearInterval(scrollTimerRef.current); + scrollTimerRef.current = null; + } + // 清理时恢复topBox样式 + topBox.style.transition = ''; + topBox.style.transform = ''; + }; + }, [hasAppended]) + + function getPointsDoc() { getPointsDocList(id).then(result=>{ let docList = []; if(result && Array.isArray(result.data.data) && result.data.data.length){ @@ -85,7 +164,6 @@ function News(props) { return item; }); } - setDocListBySecondDir(docList); }); } @@ -132,18 +210,28 @@ function News(props) { {secondDir &&
{/* */} {/* {window.scrollTo(0,450)}} className="font-18 font-bd">{secondDir.name} */} - {docListBySecondDir.map(item=>{ - return
-

- {window.scrollTo(0,450)}}>{item.name} -

-
- {item.summary} + +
+
+ {docListBySecondDir.map((item, index)=>{ + return
+

+ {window.scrollTo(0,450)}}>{item.name} +

+
+ {item.summary} +
+ 查看详情
- 查看详情 + })}
- })} - {docListBySecondDir && !docListBySecondDir.length &&
} + {docListBySecondDir && !docListBySecondDir.length &&
} +
}
diff --git a/src/forge/Information/Pages/homepage/index.scss b/src/forge/Information/Pages/homepage/index.scss index a4877fce6..22699bf71 100644 --- a/src/forge/Information/Pages/homepage/index.scss +++ b/src/forge/Information/Pages/homepage/index.scss @@ -895,30 +895,9 @@ background-blend-mode: multiply; padding: 30px 25px; max-height:653px; - overflow-y: auto; - position: relative; overflow: hidden; - backdrop-filter: blur(12px); - &::before{ - content: ''; - position: absolute; - left: 0; right: 0; - height: 60px; - z-index: 3; - pointer-events: none; - top: 0; - background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), transparent); - } - &::after{ - content: ''; - position: absolute; - left: 0; right: 0; - height: 60px; - z-index: 3; - pointer-events: none; - bottom: 0; - background: linear-gradient(to top, rgba(255, 255, 255, 0.8), transparent); - } + } + .topBox{ } .docBySecondDir_NSCC{ cursor: pointer; @@ -934,7 +913,7 @@ a.font-14{ color: $primary-color; } - &:hover{ + &:hover, &.active{ background-image: url('./image/bkImg7.png'); background-size: 100% 100%; div, a, p{