React中通过类名绑定scroll事件调用preventDefault的正确方法
现有代码失效原因
你的代码没达到效果,核心是三个错误:
- 调用
addEventListener时第一个参数传了空字符串,没有指定要监听的事件类型,相当于没绑定任何有效监听 - 选中的
.ScrollbarLayout_faceVertical是自定义滚动条的拖动滑块元素,不是实际承载滚动内容、触发滚动行为的容器 - 普通的
scroll事件监听无法被preventDefault阻止,且现代浏览器默认把滚动相关事件设为passive: true,默认不允许在监听里调用阻止默认行为的方法,必须手动修改监听配置。
正确实现代码
首先先定位真正的滚动容器:第三方自定义滚动条生成的元素里,带overflow: auto/scroll样式、包裹实际滚动内容的元素才是你要绑定事件的目标,不要选滚动条轨道、滑块这类UI元素。
useEffect(() => { // 替换成你实际找到的滚动容器选择器 const scrollContainer = document.querySelector('替换成你的滚动容器类名/选择器'); if (!scrollContainer) return; const preventScroll = (e) => { e.preventDefault(); e.stopPropagation(); }; // 监听配置必须写:捕获阶段触发 + 关闭passive模式,才能让preventDefault生效 const listenerOption = { capture: true, passive: false }; // 拦截所有触发滚动的输入行为,不要只监听scroll事件 // 鼠标滚轮 scrollContainer.addEventListener('wheel', preventScroll, listenerOption); // 移动端触摸滑动 scrollContainer.addEventListener('touchmove', preventScroll, listenerOption); // 键盘触发的滚动:方向键、PageUp/PageDown、空格 scrollContainer.addEventListener('keydown', (e) => { const scrollKeyCodes = [32, 33, 34, 37, 38, 39, 40]; if (scrollKeyCodes.includes(e.keyCode)) { e.preventDefault(); } }, listenerOption); // 组件卸载时移除事件监听,避免内存泄漏 return () => { scrollContainer.removeEventListener('wheel', preventScroll, listenerOption); scrollContainer.removeEventListener('touchmove', preventScroll, listenerOption); }; }, []);
补充说明:如果第三方库本身提供了禁用滚动的配置项,优先用库自带的配置,优先级比手动绑定DOM事件更高。如果实在找不到库生成的滚动容器,可以在你调用第三方滚动组件的外层自己套一层固定高度的div,把事件绑定在你自己写的这层容器上做拦截,不用依赖第三方生成的类名。
内容的提问来源于stack exchange,提问作者Jhon
相关产品推荐
相关产品推荐

