为什么给 scroll 事件加 passive: true 后 preventDefault 不生效了?

百里春景 阅读 3

我在做一个自定义下拉刷新功能,需要监听 scroll 事件并阻止默认滚动,但加上 passive: truepreventDefault() 就报错了,说不能在 passive 事件里调用。可不加又会有性能警告,这咋办?

这是我的监听代码:

window.addEventListener('scroll', function(e) {
  if (scrollTop < 0) {
    e.preventDefault(); // 这里报错:Unable to preventDefault inside passive event listener
    // 自定义下拉逻辑...
  }
}, { passive: true });
我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
IT人英杰
这问题我也踩过坑。passive: true 就是告诉浏览器你不会调用 preventDefault,所以它就能优化滚动性能。但你要阻止默认滚动,这俩需求冲突了。

解决方案是用两个监听器,一个 passive 的用来检测位置,另一个非 passive 的来阻止默认行为。直接上代码:

let shouldPrevent = false;

// passive监听器只检测不阻止
window.addEventListener('scroll', function() {
shouldPrevent = window.scrollTop < 0;
}, { passive: true });

// 非passive监听器实际阻止
window.addEventListener('scroll', function(e) {
if (shouldPrevent) {
e.preventDefault();
// 你的下拉刷新逻辑
}
});


其实这种下拉刷新最好用 touch 事件做,滚动事件坑太多了。不过你要非用 scroll 的话,上面这招能解决问题。
点赞
2026-03-05 23:19