React Indiana Drag Scroll容器子元素onClick不触发,如何实现点击滚动?
解决React-Indiana-Drag-Scroll中ScrollContainer子元素点击事件不触发的问题
问题根源
React-Indiana-Drag-Scroll的ScrollContainer组件为了实现拖拽滚动逻辑,会在内部拦截mousedown/mousemove这类鼠标事件,甚至会阻止事件冒泡或默认行为。而onClick事件依赖mousedown+mouseup的完整事件链,一旦中间环节被容器拦截,子元素的点击事件就完全无法触发。
可行解决方案
方案1:利用库自带配置放行指定标签事件
该库提供了ignoreEventsOnTags属性,可以指定哪些标签的事件不被容器拦截。直接把你要添加点击事件的子元素标签(比如div)加入配置即可:
import ScrollContainer from 'react-indiana-drag-scroll'; import { useRef } from 'react'; function YourComponent() { const divRef = useRef(null); const divRef2 = useRef(null); const childOnClick = (ref) => { if (ref.current) { ref.current.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); } }; return ( <ScrollContainer ignoreEventsOnTags={['div']}> <div ref={divRef} onClick={() => childOnClick(divRef)}> <h3>Div Text</h3> </div> <div ref={divRef2} onClick={() => childOnClick(divRef2)}> <h3>Div Text</h3> </div> <div> <h3>Div Text</h3> </div> </ScrollContainer> ); }
方案2:手动阻止子元素事件冒泡
如果不想全局放行某类标签,也可以给单个子元素添加mousedown事件,手动阻止事件传递到ScrollContainer:
<div ref={divRef} onClick={() => childOnClick(divRef)} onMouseDown={(e) => e.stopPropagation()} > <h3>Div Text</h3> </div>
这样容器不会接收到该子元素的mousedown事件,自然不会拦截后续的mouseup和click事件,你的点击逻辑就能正常执行。
额外优化:简化代码逻辑
你完全可以不用单独声明多个ref,直接通过事件对象的currentTarget获取点击元素,省去重复的ref定义:
import ScrollContainer from 'react-indiana-drag-scroll'; function YourComponent() { const childOnClick = (e) => { e.currentTarget.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); }; return ( <ScrollContainer ignoreEventsOnTags={['div']}> <div onClick={childOnClick}> <h3>Div Text</h3> </div> <div onClick={childOnClick}> <h3>Div Text</h3> </div> <div onClick={childOnClick}> <h3>Div Text</h3> </div> </ScrollContainer> ); }
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

