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

一静静 阅读 4

我在做一个自定义下拉刷新功能,需要监听 touchmove 事件并调用 e.preventDefault() 来阻止页面滚动。但 Chrome 控制台一直警告我“Consider marking event handler as ‘passive’ to make the page more responsive”。于是我加上了 { passive: true },结果发现 preventDefault 完全没用了,页面照样滚动。

我试过改成 { passive: false },警告没了,功能也正常了,但又担心性能问题。到底该怎么处理这种情况?是不是某些场景下就不能用 passive?

document.addEventListener('touchmove', function(e) {
  if (isPullingDown) {
    e.preventDefault(); // 加了 passive: true 后这行无效
    // ...其他逻辑
  }
}, { passive: true });
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
紫晨的笔记
passive: true 的事件监听器不能调用 e.preventDefault(),这是设计如此。要解决你的问题,要么放弃 passive,要么在 touchstart 时判断条件并设置 passive 属性。检查一下这个写法:

let supportsPassive = false;
try {
window.addEventListener('test', null, Object.defineProperty({}, 'passive', {
get: function() { supportsPassive = true; }
}));
} catch(e) {}

document.addEventListener('touchmove', function(e) {
if (isPullingDown && !supportsPassive) {
e.preventDefault();
}
}, supportsPassive ? { passive: false } : false);


这样能避免警告又保持功能正常,虽然有点绕但确实管用。唉,浏览器兼容性就是这么折腾人。
点赞
2026-03-30 22:05