react-horizontal-scrolling-menu滚动异常、箭头失效问题求助
问题现象
- 执行滚动操作时组件大幅向右偏移,其余列表元素消失不可见
- 外层Box组件添加
overflowX: 'scroll'样式时,完成首次点击操作前滚动功能完全无法触发 - 自定义传入的
LeftArrow、RightArrow箭头组件点击无响应,无法正常触发滚动
问题根因
- 箭头点击无响应:自定义箭头的className写反,点击事件未做冒泡阻止,组件内部容器事件拦截了箭头的点击触发;同时未做边界状态判断,首尾位置时箭头点击本身也不会产生滚动效果
- 滚动大幅偏移、元素消失:ScrollMenu外层容器设置了
position: static覆盖了组件默认的定位规则,导致滚动偏移量计算错误;若子项itemId存在非字符串、重复值的情况,也会触发滚动位置计算异常 - 首次点击前滚动失效:外层容器手动添加
overflowX: 'scroll'和组件自带的滚动容器逻辑冲突,组件本身已经封装了滚动容器实现,不需要额外在外层设置横向滚动属性
修复步骤
- 移除外层Box多余的
overflowX: 'scroll'样式,保留组件自带的滚动容器实现 - 修正箭头组件的className,给箭头点击事件添加阻止冒泡逻辑,补充首尾位置的箭头显隐判断
- 移除ScrollMenu外层包裹Box的
position: 'static'设置,保证组件内部定位计算正常 - 将子项的
itemId统一转为字符串格式,确保所有子项id唯一,避免滚动计算错误
修正后代码
外层调用代码
<Box component="div" sx={{position:'relative', width:'100%',p:'20px'}}> <HorizontalScrollbar data={bodyParts} bodyParts={bodyParts} bodyPart={bodyPart} setBodyPart={setBodyPart}/> </Box>
HorizontalScrollbar组件实现代码
import React, { useContext, useCallback } from 'react'; import { ScrollMenu, VisibilityContext } from 'react-horizontal-scrolling-menu'; import { Box, Typography } from '@mui/material'; import BodyPart from './BodyPart'; import RightArrowIcon from '../assets/icons/right-arrow.png'; import LeftArrowIcon from '../assets/icons/left-arrow.png'; const LeftArrow = () => { const { isFirstItemVisible, scrollPrev } = useContext(VisibilityContext); const handleClick = useCallback((e) => { e.stopPropagation(); scrollPrev(); }, [scrollPrev]); return ( <Typography onClick={handleClick} className="left-arrow" sx={{ visibility: isFirstItemVisible ? 'hidden' : 'visible', cursor: 'pointer', position: 'absolute', left: 0 }} > <img src={LeftArrowIcon} alt="left-arrow" /> </Typography> ); }; const RightArrow = () => { const { isLastItemVisible, scrollNext } = useContext(VisibilityContext); const handleClick = useCallback((e) => { e.stopPropagation(); scrollNext(); }, [scrollNext]); return ( <Typography onClick={handleClick} className="right-arrow" sx={{ visibility: isLastItemVisible ? 'hidden' : 'visible', cursor: 'pointer', position: 'absolute', right: 0 }} > <img src={RightArrowIcon} alt="right-arrow"/> </Typography> ); }; const HorizontalScrollbar = ({ data, bodyParts, setBodyPart, bodyPart }) => ( <Box mt={4}> <ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}> {data.map((item) => ( <Box key={item.id || item} itemId={String(item.id || item)} title={item.id || item} m="0 40px" > <BodyPart item={item} setBodyPart={setBodyPart} bodyPart={bodyPart} /> </Box> ))} </ScrollMenu> </Box> ); export default HorizontalScrollbar;
补充:如果修复后仍出现滚动偏移问题,检查BodyPart组件内部是否设置了超出预期的固定宽度、负margin样式,避免子项尺寸计算错误。
内容的提问来源于stack exchange,提问作者Ruba Khalil
相关产品推荐
相关产品推荐

