页面滚动失灵?这些方法帮你快速修复

// 模拟触屏滑动
const touchStart = new TouchEvent('touchstart', {
  touches: [new Touch({ identifier: 1, target: document.body, clientX: 0, clientY: 0 })],
});
const touchMove = new TouchEvent('touchmove', {
  touches: [new Touch({ identifier: 1, target: document.body, clientX: 0, clientY: -100 })],
});

// 监听 touchmove 是否被阻止
document.addEventListener('touchmove', (e) => {
  console.log('Touchmove defaultPrevented:', e.defaultPrevented);
}, { passive: true });

// 触发事件
document.dispatchEvent(touchStart);
document.dispatchEvent(touchMove);

这段代码模拟了在触屏设备上的滑动操作,并监听 touchmove 事件是否被阻止。

以下是对代码的详细解析:

1. 创建 touchstart 事件

const touchStart = new TouchEvent('touchstart', {
  touches: [new Touch({ identifier: 1, target: document.body, clientX: 0, clientY: 0 })],
});
  • TouchEvent: 创建一个 touchstart 事件,表示用户开始触摸屏幕。

  • touches: 这是一个 TouchList,包含当前所有触摸点的信息。这里只包含一个触摸点。

  • Touch: 表示一个触摸点,identifier 是触摸点的唯一标识符,target 是触摸的目标元素(这里是 document.body),clientX 和 clientY 是触摸点的坐标(这里是 (0, 0))。

2. 创建 touchmove 事件

const touchMove = new TouchEvent('touchmove', {
  touches: [new Touch({ identifier: 1, target: document.body, clientX: 0, clientY: -100 })],
});
  • touchmove: 创建一个 touchmove 事件,表示用户在屏幕上移动手指。

  • touches: 同样包含一个触摸点,但这次 clientY 的值变为 -100,表示手指向上移动了 100 像素。

3. 监听 touchmove 事件

document.addEventListener('touchmove', (e) => {
  console.log('Touchmove defaultPrevented:', e.defaultPrevented);
}, { passive: true });
  • addEventListener: 监听 touchmove 事件。

  • e.defaultPrevented: 检查事件的 defaultPrevented 属性,如果为 true,表示事件的默认行为被阻止(例如,调用了 e.preventDefault())。

  • { passive: true }: 表示事件监听器是被动的,不会调用 preventDefault()。这通常用于优化性能,尤其是在处理滚动等操作时。

4. 触发事件

document.dispatchEvent(touchStart);
document.dispatchEvent(touchMove);
  • dispatchEvent: 手动触发 touchstart 和 touchmove 事件,模拟用户触摸屏幕并移动手指的操作。

5. 输出结果

  • 当 touchmove 事件触发时,控制台会输出 Touchmove defaultPrevented: false,因为事件监听器是被动的,没有调用 preventDefault(),所以 defaultPrevented 为 false

总结

这段代码模拟了用户在触屏设备上从 (0, 0) 滑动到 (0, -100) 的操作,并检查 touchmove 事件的默认行为是否被阻止。由于事件监听器是被动的,默认行为不会被阻止。

 

如果检测到了touch阻挡了滚动,可以尝试以下代码解除限制

(function() {
  // 保存原始 addEventListener
  const originalAdd = EventTarget.prototype.addEventListener;

  // 重写 addEventListener
  EventTarget.prototype.addEventListener = function(type, listener, options) {
    // 仅监控 touchmove
    if (type === 'touchmove') {
      // 包装原始监听器
      const wrappedListener = function(e) {
        const hasPreventDefault = e.defaultPrevented;
        const stack = new Error().stack; // 获取调用堆栈
        try {
          listener.apply(this, arguments);
        } finally {
          if (e.defaultPrevented && !hasPreventDefault) {
            console.log(
              '🚨 发现阻止滚动的 touchmove 监听器:',
              '\n- 元素:', this,
              '\n- 调用栈:', stack
            );
          }
        }
      };

      // 替换原始监听器
      return originalAdd.call(this, type, wrappedListener, options);
    }

    // 其他事件正常处理
    return originalAdd.apply(this, arguments);
  };

  console.log('Touchmove 监听器监控已启用!');
})();

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值