// 模拟触屏滑动
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 监听器监控已启用!');
})();
4827

被折叠的 条评论
为什么被折叠?



