好的,这是一些奇怪的Safari行为。
摘要:
假设我要禁用网页上的上下文菜单。但是,当用户右键单击蓝色正方形时,我要运行openSpecialMenu()
。为了匹配此所需的行为,我有:
contextmenu
事件监听器,调用event.preventDefault()
。这样可以防止出现上下文菜单。contextmenu
事件监听器,调用openSpecialMenu()
。现在,假设我的特殊菜单会像大多数弹出菜单一样在click
事件上自行关闭。
我在以下代码段中重新创建了此场景:
document.addEventListener('contextmenu', function(event) {
event.preventDefault();
console.log('document contextmenu prevented');
});
document.getElementById("thing").addEventListener('contextmenu', function(event) {
console.log('blue square contextmenu');
// This opens my special menu.
// openSpecialMenu();
});
document.getElementById("thing").addEventListener('click', function(event) {
console.log('blue square click');
// My special menu closes if this is run.
});
document.getElementById("thing").addEventListener('mouseup', function(event) {
console.log('blue square mouseup');
// My special menu closes if this is run.
});
#thing {
height: 100px;
width: 100px;
background: blue;
}
<div id="thing"></div>
在Safari上浏览一下。使用CTRL +单击,在控制台打开的情况下,在Codepen输出中的蓝色方块上“右键单击”。请注意,事件是按以下顺序触发的:
blue square contextmenu
document contextmenu prevented
blue square click
这看起来似乎还不错...除了这个blue square click
事件。您可能想知道为什么在按住CTRL的情况下在Safari上触发了click
事件?contextmenu
事件不应该那样吃吗?
现在注释掉event.preventDefault()
,然后重试。请注意,这次没有显示blue square click
控制台日志。发生什么事了?
我愚蠢的直观理论:
使用contextmenu
阻止preventDefault
事件会使Safari将事件视为click
事件。 AFAIK,这仅是Safari的行为,无法在Chrome,Edge,FF上进行复制。
为什么会出现问题?
如果在这里触发了click
个事件,那么我的特殊菜单将在打开后立即关闭。我的函数openSpecialMenu()
被正确调用,但是之后立即触发click
事件,并且特殊菜单再次关闭。
我的问题:
click
事件之后是否迅速触发了contextmenu
事件……但是我正在寻找更强大的工具。