移动端使用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的事件监听逻辑:
- 找到
node_modules/react-scratchcard-v2/src/下的源码文件; - 定位到
touchstart、touchmove的事件监听代码; - 将监听选项改为
{ 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
相关产品推荐
相关产品推荐

