如何根据Div块内元素状态隐藏自定义滚动Prev/Next按钮
实现滚动容器的按钮显示/隐藏逻辑
要实现滚动到第一个元素时隐藏Prev按钮、滚动到最后一个元素时隐藏Next按钮、中间位置显示双按钮的效果,我们可以通过监听滚动容器的滚动事件,结合容器的滚动参数判断按钮显示状态,具体修改如下:
修改后的完整代码
import { useRef, useState, useEffect } from "react"; export default function App() { const cardsContainerRef = useRef(); const [showPrevBtn, setShowPrevBtn] = useState(false); const [showNextBtn, setShowNextBtn] = useState(true); const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; const updateButtonVisibility = () => { const container = cardsContainerRef.current; if (!container) return; // 滚动到最左侧时隐藏Prev按钮(留5px容差避免浏览器精度问题) const isAtStart = container.scrollLeft <= 5; // 滚动到最右侧时隐藏Next按钮 const isAtEnd = container.scrollLeft + container.clientWidth >= container.scrollWidth - 5; setShowPrevBtn(!isAtStart); setShowNextBtn(!isAtEnd); }; const onPrevorNextBtnClick = (scrollOffset) => { cardsContainerRef.current.scrollLeft += scrollOffset; // 延迟更新状态,确保滚动动作完成后再判断位置 setTimeout(updateButtonVisibility, 100); }; useEffect(() => { const container = cardsContainerRef.current; if (!container) return; // 初始渲染时同步按钮状态 updateButtonVisibility(); // 添加滚动事件监听 container.addEventListener("scroll", updateButtonVisibility); // 组件卸载时清理监听,避免内存泄漏 return () => { container.removeEventListener("scroll", updateButtonVisibility); }; }, []); return ( <div> <div style={{ display: "flex", gap: "10px", alignItems: "center" }}> {showPrevBtn && ( <button onClick={() => onPrevorNextBtnClick(-300)} > Prev </button> )} <div ref={cardsContainerRef} style={{ display: "flex", gap: "10px", overflow: "hidden", width: "500px" }} > {data.map((item, index) => ( <div key={index} style={{ width: "100px", height: "100px", flexShrink: 0, backgroundColor: "green", color: "white", display: "flex", alignItems: "center", justifyContent: "center" }} > {item} </div> ))} </div> {showNextBtn && ( <button onClick={() => onPrevorNextBtnClick(300)} > Next </button> )} </div> </div> ); }
关键逻辑说明
- 状态控制:通过
showPrevBtn和showNextBtn两个状态变量,直接控制对应按钮的渲染与否 - 滚动位置判断:
scrollLeft:容器已滚动的水平距离clientWidth:容器的可见区域宽度scrollWidth:容器内所有内容的总宽度- 增加5px容差是为了避免浏览器滚动精度误差导致的状态判断异常
- 事件监听与清理:在组件挂载时添加滚动监听,初始渲染同步一次状态;卸载时移除监听,防止内存泄漏
- 按钮点击后的状态更新:由于滚动是异步行为,通过
setTimeout延迟执行状态判断,确保滚动动作完成后再更新按钮显示状态
内容的提问来源于stack exchange,提问作者bovop4
相关产品推荐
相关产品推荐

