React中使用useRef实现Div横向滚动左右按钮禁用(右按钮求助)
实现右滚动按钮的禁用逻辑
你当前右按钮的判断公式有误,正确的右滚动到底的判断条件是:当元素的已滚动距离(scrollLeft) + 可见宽度(clientWidth) 大于等于**内容总宽度(scrollWidth)**时,说明已经滚到最右侧,无法继续向右滚动。
关键属性说明
scrollLeft:元素已滚动的水平像素值clientWidth:元素可见区域的宽度(不含滚动条)scrollWidth:元素内容的总宽度(包括溢出不可见的部分)
修改后的完整代码
const cardContainerRef = useRef<HTMLDivElement | null>(null); const [scrollPos, setScrollPos] = useState(0); useEffect(() => { const handleScroll = () => { if (!cardContainerRef.current) return; setScrollPos(cardContainerRef.current.scrollLeft); }; const container = cardContainerRef.current; container?.addEventListener('scroll', handleScroll); return () => { container?.removeEventListener('scroll', handleScroll); }; }, []); // 计算是否能向右滚动 const canScrollRight = () => { if (!cardContainerRef.current) return true; const { scrollLeft, clientWidth, scrollWidth } = cardContainerRef.current; // 留1px误差值,避免因浮点精度问题导致判断错误 return scrollLeft + clientWidth < scrollWidth - 1; }; return ( <> <button style={{ opacity: scrollPos === 0 ? "50%" : "100%" }} disabled={scrollPos === 0} onClick={() => { cardContainerRef.current?.scrollBy({ left: -200, behavior: 'smooth' }); }} > <Image src={LeftArrow} alt='向左滚动' className='rotate-90' /> </button> <button style={{ opacity: canScrollRight() ? "100%" : "50%" }} disabled={!canScrollRight()} onClick={() => { cardContainerRef.current?.scrollBy({ left: 200, behavior: 'smooth' }); }} > <Image src={RightArrow} alt='向右滚动' className='-rotate-90' /> </button> </> );
优化点说明
- 修正判断逻辑:用
scrollLeft + clientWidth >= scrollWidth判断是否到最右侧,加1px误差避免浮点精度问题 - 增加disabled属性:仅修改透明度不足以阻止用户点击,添加
disabled属性让按钮真正不可交互 - 使用scrollBy替代直接修改scrollLeft:
scrollBy更符合语义,还可以添加behavior: 'smooth'实现平滑滚动(可选) - 抽离判断函数:把右滚动判断逻辑抽成函数,代码更清晰易维护
- 变量命名规范:把
ScrollPos改成小驼峰scrollPos,符合React/JS的命名习惯
内容的提问来源于stack exchange,提问作者Muneeb
相关产品推荐
相关产品推荐

