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

IT技术 javascript greasemonkey tampermonkey ctrl modifier-key
2021-01-20 16:45:35

我试图让一个脚本运行时Ctrl+ Alt+e被按下。
Tampermonkey 如何同时触发 ctrl、alt 和 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();
    }
  });
})();

4个回答

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

  • ctrlKey     -- 还按下了“控制”键。
  • shiftKey   -- 还按下了“Shift”键。
  • altKey       --“Alt”键也被按下了。
  • metaKey     -- "Meta" 键也被按下。

其他重要说明

  1. which属性已弃用
  2. 使用keydown是因为Chrome 不会keypress为已知的键盘快捷键触发事件。
  3. 某些规范的属性,例如key在 Firefox仅部分起作用
  4. 您不需要将代码包装在像 Tampermonkey(或 Greasemonkey 或大多数用户脚本引擎)那样的匿名函数中。自动提供范围保护。

因此,您的代码将变为:

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

运行这个方便的演示(现已更新,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>

zEvent.codeChrome 中不存在,在我意识到这一点之前我一直没有定义,你应该zEvent.key改用。
2021-03-21 16:45:35
@CarlosMafla,它仍然可以正常工作。在 Chrome 65.0.3325.181 和其他几个浏览器中重新验证。您使用的是什么浏览器版本和操作系统?
2021-03-22 16:45:35
仅供参考,失败在Firefox上OSX因为按下“ALT” +“E”打印出这个字:´在事件触发器上,该zEvent.key属性将´代替e我通过使用 Ctrl + Shift + e 解决了这个问题,但请记住跨平台!
2021-04-01 16:45:35
@Gideon,是的,但根据我的经验,这种用例非常罕见。
2021-04-09 16:45:35
很有见地。对于使用修饰符和只有一个目标键代码的情况,看起来是一种更简单的解决方案。对于多个键,您必须跟踪使用keydown选择的内容keyup
2021-04-11 16:45:35

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

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

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

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

我无法让 Firefox 识别 Alt Gr 与字母键的组合,只能识别与普通 Alt 的组合。所以我使用了这个方法,虽然我不得不修改它并修复它。它有一些不太理想的逻辑。但它的核心思想当然有效。但请注意,如果您的键事件函数是包含等待的异步函数,则 keyup 事件永远不会触发!所以这个问题需要额外的逻辑。但最终,这一切都运行良好。我找到了真正的解决方案 event.getModifierState('AltGraph'),这正是我从一开始就真正在寻找的。
2021-03-21 16:45:35
对于“Control”、“Shift”、“Alt”等修饰键,这不是一个好方法
2021-04-08 16:45:35

如果您像我一样来到这里了解如何检测“Alt Gr”键与字母键的组合,那么诸如 event.altKey 之类的属性不能用于此,因为没有 event.AltGrKey财产。

在这种情况下,您可以使用

event.getModifierState('AltGraph')

有关更多详细信息,请参阅https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState

我正在使用hotkeys-js来抽象功能,但仍然必须让用户选择他自己的自定义快捷方式(事先不知道)。然后我尝试了@Brock Adams 的回答,以获得在输入​​框中按下的快捷方式的 hotkeys-js 的等效格式。

我在试验时发现的东西(在 Chrome 92 上的意大利 QWERTY 键盘布局上):

  • 每个 AltGr 字符都会“丢失”修饰符属性。AltGr 可以替换为 Ctrl+Alt 组合。所以Ctrl+Alt+E(如在 OP 问题中)给出. 也是如此Ctr+Alt+5其他组合也有同样的问题,比如Ctrl+Alt+ò意大利语键盘上的@
  • 每个 Shifted 字符都被发现,e.key因为它是移动的对应物,保留了修饰符属性,因此Shift+5打印出来Shift+%是有问题的(考虑到 AltGr 行为)。
  • 某些组合无论如何都不会触发事件。我发现为例Ctrl+Shift+9Ctrl+Shift+0Ctrl+Shift+LCtrl+Shift+Alt+D我的键盘上。这可能是薄膜键盘的局限性。

第二点对我来说很重要,因为我们的客户习惯于 Ctrl+Shift+[Number] 组合。

我通过处理 keyCode 介于 48 和 58 之间的特殊情况并手动转换为相应的数字来解决它。它仍然没有解决任何其他用 Shift 修改的特殊字符,但鉴于它们非常依赖于键盘布局,我没有看到任何通用的解决方案。不过,我从来不知道有人想要带有特殊字符的快捷方式。

const input = document.getElementById("keyPrssInp");
input.addEventListener('keydown', e => {
  input.value = `${e.ctrlKey ? 'ctrl+' : ''}${e.shiftKey ? 'shift+' : ''}${e.altKey ? 'alt+' : ''}${e.metaKey ? 'meta+' : ''}${["Control", "Shift", "Alt", "Meta"].includes(e.key) ? "" : (e.keyCode < 58 && e.keyCode > 47 ? e.keyCode - 48 : e.key)}`
  e.preventDefault();
});
Press keys in here: <input type="text" value="" id="keyPrssInp">

如果不要求可读性和/或您事先知道要检查的组合键,则使用event.keyCode而不是event.key可能更安全。