You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:21:42