React实现鼠标滚轮控制垂直轮播效果求助(参考realticket.com)
React实现鼠标滚轮控制垂直轮播
核心实现思路
通过监听鼠标滚轮事件,根据滚动方向切换全屏轮播项,结合原生平滑滚动实现类似目标网站的效果。以下是完整可运行的实现方案:
1. 基础组件结构
先搭建全屏轮播的基础布局,每个轮播项占满视口高度:
import { useState, useEffect, useRef } from 'react'; import './VerticalCarousel.css'; const VerticalCarousel = () => { // 轮播数据示例 const slides = [ { id: 1, content: '轮播项 1', bgColor: '#f5f5f5' }, { id: 2, content: '轮播项 2', bgColor: '#e0e0e0' }, { id: 3, content: '轮播项 3', bgColor: '#bdbdbd' }, { id: 4, content: '轮播项 4', bgColor: '#9e9e9e' }, ]; const [currentIndex, setCurrentIndex] = useState(0); const slidesRef = useRef([]); const isScrolling = useRef(false); // 防止滚动频繁触发 const scrollThrottle = 800; // 节流间隔(毫秒)
2. 滚轮事件监听与处理
添加滚轮事件监听,判断滚动方向并切换轮播项,同时做节流处理:
useEffect(() => { const handleWheel = (e) => { if (isScrolling.current) return; // deltaY>0为向下滚动,deltaY<0为向上滚动 const direction = e.deltaY > 0 ? 'down' : 'up'; isScrolling.current = true; setTimeout(() => { isScrolling.current = false; }, scrollThrottle); // 更新轮播索引,控制边界 if (direction === 'down' && currentIndex < slides.length - 1) { setCurrentIndex(prev => prev + 1); } else if (direction === 'up' && currentIndex > 0) { setCurrentIndex(prev => prev - 1); } }; window.addEventListener('wheel', handleWheel); return () => window.removeEventListener('wheel', handleWheel); }, [currentIndex, slides.length]);
3. 平滑滚动到目标轮播项
索引变化时,让对应轮播项滚动到视口顶部:
useEffect(() => { slidesRef.current[currentIndex]?.scrollIntoView({ behavior: 'smooth', block: 'start', }); }, [currentIndex]);
4. 渲染轮播项
绑定ref获取DOM元素,渲染全屏轮播项:
return ( <div className="carousel-container"> {slides.map((slide, index) => ( <div key={slide.id} ref={el => slidesRef.current[index] = el} className="carousel-slide" style={{ backgroundColor: slide.bgColor }} > <div className="slide-content"> {slide.content} </div> </div> ))} </div> ); }; export default VerticalCarousel;
5. 配套CSS样式
创建VerticalCarousel.css文件,设置全屏布局:
.carousel-container { width: 100%; height: 100vh; overflow: hidden; } .carousel-slide { width: 100%; height: 100vh; display: flex; align-items: center; justify-content: center; font-size: 2rem; }
关键优化点
- 节流处理:通过标记位和定时器,避免短时间内多次触发滚动事件,防止轮播切换过于频繁。
- 边界控制:严格判断索引范围,防止超出轮播项总数。
- 原生平滑滚动:利用
scrollIntoView的smooth行为实现过渡,无需额外动画库。 - 内存防护:组件卸载时移除滚轮事件监听,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Bhanu Prasad
相关产品推荐
相关产品推荐

