似乎在处理指针事件时,contextmenu
事件将导致pointerout
,pointercancel
和pointerleave
事件,但随后的pointerup
s和pointermove
s将被忽略。
这在触摸设备上成为一个相当大的问题,长按会导致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
但没有pointermove
或pointerup
或touchmove
或touchend
事件。
我想我找到了答案:
noContext.addEventListener('touchstart', e => e.preventDefault());
之后,上下文菜单永远不会被长触摸触发,连续的pointermove
和touchmove
事件可用,pointerup
和touchend
事件仍然在结束时触发。
您可以通过侦听并取消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内触发时做任何事情。