防止菜单键显示上下文菜单

3
我知道 键盘菜单键keyCode === 93

所以我有以下代码:

$(window).on("keydown", document, function(event){
    if (event.keyCode === 93)  {   //context menu
        console.log("context menu key", event);
        event.preventDefault();
        event.stopPropagation();
        return false;
    }
});

尽管事件确实会被触发并且if语句内的console也会被记录,但即使在我的代码中同时存在event.preventDefault()和event.stopPropagation(),上下文菜单仍然会显示。
有没有什么方法可以阻止菜单被显示?
演示可在以下链接中查看:http://jsfiddle.net/maniator/XJtpc/

对于那些不知道“菜单”键是什么的人:


你想让右键菜单正常工作吗?如果不是,请使用绑定到contextmenu事件而不是keydown。 - aquinas
现代浏览器具有设置,可以防止您阻止上下文菜单。 - epascarello
@aquinas 我希望右键菜单能够正常工作。我不想阻止它... - Naftali
@Bot,你显然没有读原帖... - Naftali
1
@Neal,你的问题不够清晰,你说事件被触发了,这对我来说意味着你的按键已经被触发,但并不意味着你的if语句也被触发了。 - Bot
显示剩余5条评论
3个回答

3

这看起来有点笨,但似乎有效:http://jsfiddle.net/XJtpc/2/ :)

$(function(){
    var lastKey=0;
    $(window).on("keydown", document, function(event){
        lastKey = event.keyCode;            
    });

    $(window).on("contextmenu", document, function(event){
        if (lastKey === 93){
            lastKey=0;
            event.preventDefault();
            event.stopPropagation();
            return false;
        }
    });
});
​

哇...太巧妙了 :-)..... 嗯,现在我必须尝试弄清楚如何玷污全局范围.... - Naftali
1
它不在全局范围内,你看我如何将其包装在jQuery的ready函数中? - aquinas
是的,但这些事件实际上不需要在ready函数中,因为它们是委托的... - Naftali
嗯,确实,使用jQuery时我倾向于以那种方式进行封装,但是是的,可以使用(function(){})()技巧。无论您喜欢哪种方式。 - aquinas
仅从测试来看(尽管由于我没有菜单键而很难),如果用户已经打开上下文菜单(右键单击)但在此期间未按下任何键,这不会阻止下一个上下文菜单的出现。当使用键盘打开时,某些浏览器可能不会触发oncontextmenu事件?还是会触发?在我这边很难进行测试。 - rlemon
@rlemon contextmenu 是一个阻塞事件。在它被清除之前,您不能再次执行它。在这种情况下,一旦事件结束,contextmenu 事件就被清除了,您就可以再次右键单击。 - Naftali

0
诀窍在于触发上下文菜单的是keyup事件,而不是keydown事件。在Chrome和Electron中,对.key为ContextMenu的keyup事件调用.preventDefault()将阻止其发生。
也就是说,你可以通过以下方式全局禁用上下文菜单键:
window.addEventListener("keyup", function(event){
    if (event.key === "ContextMenu") event.preventDefault();
}, {capture: true})

然后监视 keydown 事件以触发您的替换。


0

我最初使用了@aquinas的解决方案,但发现它可以比那更简单。

步骤

  1. 注册keydown事件处理程序。不需要e.preventDefault
  2. 注册contextmenu事件处理程序,只需执行e.preventDefault()

示例:

// JavaScript
// Register your `ContextMenu` key event handler
document.querySelector('body').onkeydown = (e) => {
  if (e.key === 'ContextMenu') {
    // Do something
  }
}

// Prevent `contextmenu` event default action
document.querySelector('body').oncontextmenu = (e) => e.preventDefault();


// jQuery
// Register your `ContextMenu` key event handler
$('body').on('keydown', (e) => {
  if (e.key === 'ContextMenu') {
    // Do something
  }
});

// Prevent `contextmenu` event default action
$('body').on('contextmenu', (e) => e.preventDefault());


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接