React Analytics页面实现滚动完整显示单个Dashboard组件需求
实现React Analytics页面Dashboard组件的滚动锁定切换效果
核心思路
将每个Dashboard组件设置为占满整个视口高度,监听滚动/触摸事件判断操作方向,直接平滑滚动到目标组件位置,同时阻止原生滚动的连续触发,确保始终只有一个完整组件显示在视口中。
实现步骤
基础布局配置
- 每个Dashboard组件设置
height: 100vh,保证单个组件刚好填满屏幕 - 页面根容器或body设置
overflow: hidden,避免原生滚动条干扰
- 每个Dashboard组件设置
滚动/触摸事件监听
- 监听鼠标滚轮事件(
wheel)和移动端触摸事件(touchstart/touchend),判断滚动/滑动方向 - 限制切换范围:只能在0到3(4个组件的索引)之间切换
- 监听鼠标滚轮事件(
平滑滚动与行为拦截
- 使用
window.scrollTo配合behavior: 'smooth'实现组件间的平滑切换 - 调用
event.preventDefault()阻止原生滚动行为,避免一次操作触发多次切换
- 使用
完整代码示例
import { useEffect, useState } from 'react'; const AnalyticsPage = () => { const [currentPanel, setCurrentPanel] = useState(0); const totalPanels = 4; useEffect(() => { // 处理鼠标滚轮 const handleWheel = (e) => { e.preventDefault(); const isScrollDown = e.deltaY > 0; if (isScrollDown && currentPanel < totalPanels - 1) { setCurrentPanel(prev => prev + 1); } else if (!isScrollDown && currentPanel > 0) { setCurrentPanel(prev => prev - 1); } }; // 处理移动端触摸滑动 let touchStartY = 0; const handleTouchStart = (e) => { touchStartY = e.touches[0].clientY; }; const handleTouchEnd = (e) => { const touchEndY = e.changedTouches[0].clientY; const isSwipeDown = touchEndY > touchStartY; if (isSwipeDown && currentPanel > 0) { setCurrentPanel(prev => prev - 1); } else if (!isSwipeDown && currentPanel < totalPanels - 1) { setCurrentPanel(prev => prev + 1); } }; // 绑定事件 window.addEventListener('wheel', handleWheel, { passive: false }); window.addEventListener('touchstart', handleTouchStart); window.addEventListener('touchend', handleTouchEnd); // 清理事件监听 return () => { window.removeEventListener('wheel', handleWheel); window.removeEventListener('touchstart', handleTouchStart); window.removeEventListener('touchend', handleTouchEnd); }; }, [currentPanel, totalPanels]); // 根据当前索引滚动到对应位置 useEffect(() => { window.scrollTo({ top: currentPanel * window.innerHeight, behavior: 'smooth' }); }, [currentPanel]); return ( <div style={{ overflow: 'hidden', height: '100vh' }}> <div className="dashboard-wrapper"> {/* 替换为你的Dashboard组件 */} <div className="dashboard-panel" style={{ height: '100vh' }}>仪表盘 1</div> <div className="dashboard-panel" style={{ height: '100vh' }}>仪表盘 2</div> <div className="dashboard-panel" style={{ height: '100vh' }}>仪表盘 3</div> <div className="dashboard-panel" style={{ height: '100vh' }}>仪表盘 4</div> </div> </div> ); }; export default AnalyticsPage;
额外优化建议
- 如果Dashboard内容超出视口高度,给组件内部添加
overflow-y: auto,实现组件内的独立滚动 - 添加键盘导航支持:监听
keydown事件,通过上下箭头键切换组件,提升 accessibility - 加入节流处理(比如用
lodash.throttle),避免快速滚动时的频繁切换
内容的提问来源于stack exchange,提问作者John Daison
相关产品推荐
相关产品推荐

