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

移动端使用react-scratchcard-v2时出现Unable to preventDefault错误

问题分析

控制台抛出的Unable to preventDefault inside passive event listener invocation错误,根源在于:

  • 移动端浏览器为提升滚动性能,默认将touchstart、touchmove这类触摸事件的监听器设为被动模式(passive: true);
  • 你使用的react-scratchcard-v2组件内部的触摸事件逻辑中调用了event.preventDefault(),但被动监听器不允许执行该方法,因此触发警告。
解决方案

方法1:CSS禁用区域默认触摸行为(推荐)

给刮刮卡容器添加touch-action: none样式,直接阻止浏览器对该区域的默认触摸行为(如滚动、缩放),从根源避免冲突:

.scratcharea-container {
  touch-action: none;
  /* 保留原有其他样式 */
}

方法2:修改组件内部事件监听配置

如果不想用CSS方案,可以调整react-scratchcard-v2的事件监听逻辑:

  1. 找到node_modules/react-scratchcard-v2/src/下的源码文件;
  2. 定位到touchstart、touchmove的事件监听代码;
  3. 将监听选项改为{ passive: false },或者移除不必要的event.preventDefault()调用。

若不想直接修改node_modules,可以用patch-package工具给依赖打补丁,方便后续版本更新。

方法3:全局覆盖被动事件设置(不推荐)

在项目入口文件中全局修改触摸事件的被动配置,此方法会影响页面整体滚动性能,仅作临时测试使用:

// 全局禁用touchstart和touchmove的被动监听
document.addEventListener('touchstart', () => {}, { passive: false });
document.addEventListener('touchmove', () => {}, { passive: false });
额外代码优化

你的代码里有两段完全重复的useEffect监听window.mouseup,删除其中一个即可减少冗余:

// 保留这一段即可
useEffect(() => {
  const handleWindowMouseUp = () => {
    if (isClicked) {
      setIsClicked(false);
      setIsScratching(false);
    }
  };
  window.addEventListener("mouseup", handleWindowMouseUp);

  return () => {
    window.removeEventListener("mouseup", handleWindowMouseUp);
  };
}, [isClicked]);

内容的提问来源于stack exchange,提问作者Michael K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:43:19