Javascript 检测组合按键(Control、Alt、Shift)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37557990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:27:42  来源:igfitidea点击:

Detecting combination keypresses (Control, Alt, Shift)?

javascriptgreasemonkeytampermonkeyctrlmodifier-key

提问by Rasspy

I am trying to make a script run when Ctrl+ Alt+ eis pressed.
How can Tampermonkey fire on a simultaneous ctrl, alt, and e key?

我试图让一个脚本运行时Ctrl+ Alt+e被按下。
Tampermonkey 如何同时触发 ctrl、alt 和 e 键?

I have tried ctrlKey, and altKey. I've found nothing that works.
How can I edit the script below to fire on Ctrl+ Alt+ e, instead of just e?

我试过了ctrlKey,而且altKey。我没有发现任何有用的东西。
如何编辑下面的脚本来火Ctrl+ Alt+ e,而不是仅仅e

(function() {
  document.addEventListener("keypress", function(e) {
    if (e.which == 101) {
      var xhttp = new XMLHttpRequest;
      xhttp.onreadystatechange = function() {
        4 == xhttp.readyState && 200 == xhttp.status && eval(xhttp.responseText)
      }, xhttp.open("GET", "http://127.0.0.1:2337/inject", !0), xhttp.send();
    }
  });
})();

回答by Brock Adams

Refer to the W3C spec for keyboard events. Several boolean attributes are provided to determine if modifier keyswere pressed in conjunction with whatever target key you are interested in. They are:

请参阅W3C 规范以了解键盘事件。提供了几个布尔属性来确定修饰键是否与您感兴趣的任何目标键一起按下。它们是:

  • ctrlKey    -- The "Control" key was also pressed.
  • shiftKey  -- The "Shift" key was also pressed.
  • altKey      -- The "Alt" key was also pressed.
  • metaKey    -- The "Meta" key was also pressed.
  • ctrlKey    -- 还按下了“控制”键。
  • shiftKey  -- 还按下了“Shift”键。
  • altKey      --“Alt”键也被按下了。
  • metaKey    -- "Meta" 键也被按下。

Other important notes:

其他重要说明

  1. The whichproperty is deprecated.
  2. Use keydownbecause Chrome does not fire the keypressevent for known keyboard shortcuts.
  3. Some spec'd properties, such as key, are only partly functional in Firefox.
  4. You do not need to wrap your code in an anonymous function like that for Tampermonkey (or Greasemonkey or most userscript engines). Scope protection is automatically provided.
  1. which属性已弃用
  2. 使用keydown是因为Chrome 不会keypress为已知的键盘快捷键触发事件。
  3. 某些规范的属性,例如key在 Firefox仅部分起作用
  4. 您不需要将代码包装在像 Tampermonkey(或 Greasemonkey 或大多数用户脚本引擎)那样的匿名函数中。自动提供范围保护。

So, your code would become:

因此,您的代码将变为:

document.addEventListener ("keydown", function (zEvent) {
    if (zEvent.ctrlKey  &&  zEvent.altKey  &&  zEvent.key === "e") {  // case sensitive
        // DO YOUR STUFF HERE
    }
} );


Run this handy demo (updated now that keyhas full support):

运行这个方便的演示(现已更新,key具有全面支持)

var targArea = document.getElementById ("keyPrssInp");
targArea.addEventListener ('keydown',  reportKeyEvent);

function reportKeyEvent (zEvent) {
    var keyStr = ["Control", "Shift", "Alt", "Meta"].includes(zEvent.key) ? "" : zEvent.key + " ";
    var reportStr   =
        "The " +
        ( zEvent.ctrlKey  ? "Control " : "" ) +
        ( zEvent.shiftKey ? "Shift "   : "" ) +
        ( zEvent.altKey   ? "Alt "     : "" ) +
        ( zEvent.metaKey  ? "Meta "    : "" ) +
        keyStr + "key was pressed."
    ;
    $("#statusReport").text (reportStr);

    //--- Was a Ctrl-Alt-E combo pressed?
    if (zEvent.ctrlKey  &&  zEvent.altKey  &&  zEvent.key === "e") {  // case sensitive
        this.hitCnt = ( this.hitCnt || 0 ) + 1;
        $("#statusReport").after (
            '<p>Bingo! cnt: ' + this.hitCnt + '</p>'
        );
    }
    zEvent.stopPropagation ();
    zEvent.preventDefault ()
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p><label>Press keys in here:<input type="text" value="" id="keyPrssInp"></label>
</p>
<p id="statusReport"></p>

回答by Gideon Pyzer

The keypressevent is fired as soon as a key has been pressed. If you are pressing multiple keys, it will fire the event for each press, so they are considered independent key presses.

keypress一旦按下某个键,就会触发该事件。如果您按下多个键,则每次按下都会触发事件,因此它们被视为独立的按键。

Instead, you can use both the keydownand keyupevents to detect multiple key presses. You can have an object that contains the 3 keys and a boolean state. On the keydownevent, if the current key matches a key in the object, you set the state to truefor that key. On the keyupevent, you reset the state for the current key to false. If all 3 states are trueat the time of the last key press, then fire the event.

相反,您可以同时使用keydownkeyup事件来检测多个按键按下。您可以拥有一个包含 3 个键和一个布尔状态的对象。在keydown事件中,如果当前键与对象中的键匹配,则将该键的状态设置true为 。在keyup事件中,您将当前密钥的状态重置为false。如果所有 3 个状态都true在最后一次按键时,则触发该事件。

See this examplethat achieves this logic using jQuery.

请参阅使用 jQuery 实现此逻辑的示例

UpdateBrock's answer is a better solution for you using modifier keys in combination with a single key code target, as the ctrlKeyand altKeymodifiers are detected in combination, not handled independently. If you want to detect multiple key codes like, Eand Ftogether, for example, you'd need to keep track of them using keydownand keyupas per above.

更新Brock 的答案对于您将修饰键与单个键代码目标结合使用是一个更好的解决方案,因为ctrlKeyaltKey修饰符是组合检测的,而不是独立处理的。例如,如果您想检测多个关键代码,例如,EF一起检测,则需要使用keydownkeyup如上所述跟踪它们。