在' contextmenu '事件之后接收指针事件



似乎在处理指针事件时,contextmenu事件将导致pointerout,pointercancelpointerleave事件,但随后的pointerups和pointermoves将被忽略。

这在触摸设备上成为一个相当大的问题,长按会导致contextmenu被触发。如果长指针的移动碰巧在一个位置停留太久,它会使其提前终止。

我找到了关于如何忽略contextmenu事件的建议。但是有可能完全禁用它,使它永远不会发射吗?特别是,它不会阻碍指针事件流?

或者长按的"长度"可以自定义吗?

编辑 一些演示此效果的代码,基于Axionatic的:

<!DOCTYPE html>
<html>
<body>
<div id="noContextMenu" style="height:150px; background-color:#ffaaaa;">
<h2>No right-clicking allowed!</h2>
</div>
<script>
const noContext = document.getElementById('noContextMenu');
noContext.addEventListener('contextmenu', e => {
console.log('contextmenu');
e.preventDefault();
});
noContext.addEventListener('pointerdown', e => console.log('pointerdown'));
noContext.addEventListener('pointerup', e => console.log('pointerup'));
noContext.addEventListener('pointercancel', e => console.log('pointercancel'));
noContext.addEventListener('pointerout', e => console.log('pointerout'));
noContext.addEventListener('pointerleave', e => console.log('pointerleave'));
noContext.addEventListener('pointermove', e => console.log('pointermove'));
noContext.addEventListener('touchstart', e => console.log('touchstart'));
noContext.addEventListener('touchmove', e => console.log('touchmove'));
noContext.addEventListener('touchend', e => console.log('touchend'));
noContext.addEventListener('touchcancel', e => console.log('touchcancel'));
</script>
</body>
</html>

在浏览器的触摸设备模拟模式下打开这个,然后尝试长按,然后在不释放触摸的情况下进一步移动指针。您应该得到这样的输出:

pointerdown
touchstart
contextmenu
pointercancel
pointerout
pointerleave
touchcancel

但没有pointermovepointeruptouchmovetouchend事件。

我想我找到了答案:

noContext.addEventListener('touchstart', e => e.preventDefault());

之后,上下文菜单永远不会被长触摸触发,连续的pointermovetouchmove事件可用,pointeruptouchend事件仍然在结束时触发。

您可以通过侦听并取消preventDefault来阻止上下文菜单事件(或任何其他事件)生效。

根据MDN Web Docs:

<div id="noContextMenu" style="height:150px; background-color:#ffaaaa;">
<h2>No right-clicking allowed!</h2>
</div>
<script>
const noContext = document.getElementById('noContextMenu');
noContext.addEventListener('contextmenu', e => {
e.preventDefault();
});
</script>

这将捕获上下文菜单事件,并防止它在id="noContextMenu"div内触发时做任何事情。

最新更新