From 0e32076e713e9acdfd7ac3cda6687334211350e7 Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Thu, 13 Nov 2025 17:31:06 +0800 Subject: [PATCH] update ui --- .../Community/components/DynamicNewsCard.js | 193 ++++-------------- 1 file changed, 37 insertions(+), 156 deletions(-) diff --git a/src/views/Community/components/DynamicNewsCard.js b/src/views/Community/components/DynamicNewsCard.js index 116e0fca..1fc78fc7 100644 --- a/src/views/Community/components/DynamicNewsCard.js +++ b/src/views/Community/components/DynamicNewsCard.js @@ -80,18 +80,10 @@ const DynamicNewsCard = forwardRef(({ // 通知权限相关 const { browserPermission, requestBrowserPermission } = useNotification(); - // 固定模式状态 - const [isFixedMode, setIsFixedMode] = useState(false); - const [headerHeight, setHeaderHeight] = useState(0); + // Refs const cardHeaderRef = useRef(null); const cardBodyRef = useRef(null); - // 导航栏和页脚固定高度 - const NAVBAR_HEIGHT = 64; // 主导航高度 - const SECONDARY_NAV_HEIGHT = 44; // 二级导航高度 - const FOOTER_HEIGHT = 80; // 页脚高度(优化后) - const TOTAL_NAV_HEIGHT = NAVBAR_HEIGHT + SECONDARY_NAV_HEIGHT; // 总导航高度 128px - // 从 Redux 读取关注状态 const eventFollowStatus = useSelector(selectEventFollowStatus); @@ -387,118 +379,7 @@ const [currentMode, setCurrentMode] = useState('vertical'); }, [handlePageChange]); // 测量 CardHeader 高度 - useEffect(() => { - const cardHeaderElement = cardHeaderRef.current; - if (!cardHeaderElement) return; - - // 测量并更新高度 - const updateHeaderHeight = () => { - const height = cardHeaderElement.offsetHeight; - setHeaderHeight(height); - }; - - // 初始测量 - updateHeaderHeight(); - - // 监听窗口大小变化(响应式调整) - window.addEventListener('resize', updateHeaderHeight); - - return () => { - window.removeEventListener('resize', updateHeaderHeight); - }; - }, []); - - // 监听 CardHeader 是否到达触发点,动态切换固定模式 - useEffect(() => { - const cardHeaderElement = cardHeaderRef.current; - const cardBodyElement = cardBodyRef.current; - if (!cardHeaderElement || !cardBodyElement) return; - - let ticking = false; - const TRIGGER_OFFSET = 150; // 提前 150px 触发(进入固定模式) - const EXIT_OFFSET = 200; // 提前 200px 退出(退出比进入更容易) - const EXIT_THRESHOLD = 30; // 接近顶部 30px 内即可退出 - - // 外部滚动监听:触发固定模式 - const handleExternalScroll = () => { - // 只在非固定模式下监听外部滚动 - if (!isFixedMode && !ticking) { - window.requestAnimationFrame(() => { - // 获取 CardHeader 相对视口的位置 - const rect = cardHeaderElement.getBoundingClientRect(); - const elementTop = rect.top; - - // 计算触发点:总导航高度 + 150px 偏移量 - const triggerPoint = TOTAL_NAV_HEIGHT + TRIGGER_OFFSET; - - // 向上滑动:元素顶部到达触发点 → 激活固定模式 - if (elementTop <= triggerPoint) { - setIsFixedMode(true); - console.log('🔒 切换为固定全屏模式', { - elementTop, - triggerPoint, - offset: TRIGGER_OFFSET - }); - } - - ticking = false; - }); - - ticking = true; - } - }; - - // 内部滚动监听:退出固定模式 - const handleWheel = (e) => { - // 只在固定模式下监听内部滚动 - if (!isFixedMode) return; - - // 检测向上滚动(deltaY < 0) - if (e.deltaY < 0) { - window.requestAnimationFrame(() => { - // 🎯 检查 1:CardHeader 位置(主要条件) - const rect = cardHeaderElement.getBoundingClientRect(); - const elementTop = rect.top; - const exitPoint = TOTAL_NAV_HEIGHT + EXIT_OFFSET; - - // 🎯 检查 2:左侧事件列表滚动位置(辅助条件) - const eventListContainers = cardBodyElement.querySelectorAll('[data-event-list-container]'); - const allNearTop = eventListContainers.length === 0 || - Array.from(eventListContainers).every( - container => container.scrollTop <= EXIT_THRESHOLD - ); - - // 🎯 退出条件:CardHeader 超过退出点 OR 左侧列表接近顶部 - if (elementTop > exitPoint || allNearTop) { - setIsFixedMode(false); - console.log('🔓 恢复正常文档流模式', { - elementTop, - exitPoint, - listNearTop: allNearTop, - exitThreshold: EXIT_THRESHOLD, - reason: elementTop > exitPoint ? 'CardHeader位置' : '左侧列表滚动' - }); - } - }); - } - }; - - // 监听外部滚动 - window.addEventListener('scroll', handleExternalScroll, { passive: true }); - - // 监听内部滚轮事件(固定模式下) - if (isFixedMode) { - cardBodyElement.addEventListener('wheel', handleWheel, { passive: true }); - } - - // 初次检查位置 - handleExternalScroll(); - - return () => { - window.removeEventListener('scroll', handleExternalScroll); - cardBodyElement.removeEventListener('wheel', handleWheel); - }; - }, [isFixedMode]); + // 固定模式逻辑已移除,改用 sticky 定位 return ( - {/* 标题部分 */} + {/* 标题和搜索部分 - 可滚动区域 */} @@ -613,36 +489,41 @@ const [currentMode, setCurrentMode] = useState('vertical'); {/* 主体内容 */} - {/* 顶部控制栏:模式切换按钮 + 筛选按钮 + 分页控制器(固定不滚动) */} - - {/* 左侧:模式切换按钮 + 筛选按钮 */} - + {/* 顶部控制栏:模式切换按钮 + 分页控制器(滚动时固定在顶部) */} + + + {/* 左侧:模式切换按钮 */} + - {/* 右侧:分页控制器(仅在纵向模式显示) */} - {mode === 'vertical' && totalPages > 1 && ( - - )} - + {/* 右侧:分页控制器(仅在纵向模式显示) */} + {mode === 'vertical' && totalPages > 1 && ( + + )} + + {/* 内容区域 - 撑满剩余高度 */}