求助:如何实现'unable to preventDefault因目标视为被动'错误的解决方案
解决"Unable to preventDefault inside passive event listener"错误
嘿,别慌!你遇到的这个问题其实是Chrome为了优化滚动性能做的默认设置导致的——对于wheel、touchstart这类和滚动相关的事件,浏览器默认会把监听器标记为passive(被动),意思是它认为你不会调用preventDefault()来阻止默认滚动行为,这样浏览器就能提前优化滚动流畅度。但你恰恰在代码里调用了preventDefault(),所以就抛出这个错误了。
你看到的解决方案是完全正确的,而且你的理解方向没出错!不需要替换掉event.preventDefault(),只要在添加事件监听器的时候,给第三个参数传入{ passive: false },明确告诉浏览器:“我这个监听器可能会阻止默认行为,别把它当成被动的”就行。
修改后的完整代码
window.addEventListener("wheel", function(event) { viewStart = scrolled.scrollTop; if (!pageJump) { var pageHeight = page.scrollHeight; var pageStopPortion = pageHeight / 2; var viewHeight = window.innerHeight; var viewEnd = viewStart + viewHeight; var pageStartPart = viewEnd - pageStart; var pageEndPart = pageStart + pageHeight - viewStart; var canJumpDown = pageStartPart >= 0; var stopJumpDown = pageStartPart > pageStopPortion; var canJumpUp = pageEndPart >= 0; var stopJumpUp = pageEndPart > pageStopPortion; var scrollingForward = event.deltaY > 0; if ( (scrollingForward && canJumpDown && !stopJumpDown) || (!scrollingForward && canJumpUp && !stopJumpUp) ) { event.preventDefault(); scrollToPage(); } // 这里原来的false可以删掉,现在浏览器已不再通过监听器返回值判断是否阻止默认行为 } // } else { // event.preventDefault(); // } }, { passive: false }); // 关键就是给addEventListener加上这个配置项!
几个小提醒
- 你原代码末尾的
false可以删掉,现在浏览器已经不依赖事件监听器的返回值来控制默认行为,完全靠preventDefault()和passive选项来决定。 - 虽然加上
{ passive: false }解决了错误,但要注意:非passive的滚动监听器可能会轻微影响滚动流畅性,不过如果你的业务逻辑确实需要阻止默认滚动(比如自定义翻页),这是必须的权衡。
内容的提问来源于stack exchange,提问作者Ghadir
相关产品推荐
相关产品推荐

