passive:true意味着绝不会​调用 preventDefault(),可放心立即执行默认行为(滚动)

为什么 touchmove不能随意使用 passive: true

被动事件监听器的设计目的

浏览器开发团队引入被动事件监听器主要是为了解决滚动性能问题:

// 传统的事件监听器可能会阻止滚动
element.addEventListener('touchmove', function(e) {
  // 如果这里有可能调用 e.preventDefault()
  // 浏览器必须等待这个函数执行完才能知道是否要滚动
});
默认passive是false

 核心矛盾点

当同时满足以下两个条件时会产生冲突:

  • 事件监听器 ​​可能​​ 调用 preventDefault()阻止默认行为

  • 但浏览器 ​​需要立即知道​​ 是否要执行默认行为(如滚动)

3. 被动事件监听器的解决方案

通过 { passive: true }明确告诉浏览器:

"这个监听器 ​​绝对不会​​ 调用 preventDefault(),你可以放心地立即执行默认行为"

element.addEventListener('touchmove', function(e) {
  // 这里绝对不能调用 e.preventDefault()
  // 浏览器可以立即执行滚动,不需要等待
}, { passive: true });
tableWrapper.addEventListener('touchmove', function(e) {
  if (!isScrolling) {
    // 这里根据条件可能会调用 e.preventDefault()
    // 所以不能使用 passive: true
  }
}, { passive: false }); // 必须设置为 false

 如果错误地使用 passive: true会怎样?

// 错误示例!
tableWrapper.addEventListener('touchmove', function(e) {
  if (shouldPreventScroll) {
    e.preventDefault(); // 这行代码会被忽略,控制台会看到警告
  }
}, { passive: true }); // 但这里声明了不会阻止默认行为

结果:

  • 浏览器会忽略 preventDefault()调用

  • 控制台会出现警告:Unable to preventDefault inside passive event listener

  • 您的滚动控制逻辑会失效

需要阻止默认行为时

// 明确声明这不是被动监听器
element.addEventListener('touchmove', handler, { passive: false });

function handler(e) {
  if (needToPrevent) {
    e.preventDefault(); // 现在可以正常工作
  }
}

不需要阻止默认行为时

// 声明为被动监听器以获得最佳性能
element.addEventListener('touchmove', handler, { passive: true });

function handler(e) {
  // 这里绝对不能调用 e.preventDefault()
  // 只是读取数据或执行不相关的逻辑
}
  • touchstart/touchend使用 passive: true(因为这些事件通常不需要阻止默认行为)

  • touchmove使用 passive: false(因为确实需要条件性地阻止滚动)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值