检测组合按键(Control、Alt、Shift)?
Detecting combination keypresses (Control, Alt, Shift)?
我正在尝试制作脚本 运行 当 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();
}
});
})();
一旦按下一个键,keypress
事件就会被触发。如果您按下多个键,它会在每次按下时触发事件,因此它们被视为独立的按键。
相反,您可以同时使用 keydown
和 keyup
事件来检测多次按键。您可以拥有一个包含 3 个键和一个布尔状态的对象。在 keydown
事件中,如果当前键与对象中的键匹配,则将该键的状态设置为 true
。在 keyup
事件中,您将当前键的状态重置为 false
。如果在最后一次按键时所有 3 个状态都是 true
,则触发事件。
参见 this example 使用 jQuery 实现此逻辑。
更新
Brock 的回答是将修饰键与单个键代码目标结合使用的更好解决方案,因为 ctrlKey
和 altKey
修饰符是组合检测的,而不是独立处理的。例如,如果您想一起检测多个键码,例如 E
和 F
,您需要使用 keydown
和 keyup
来跟踪它们.
参考the W3C spec for keyboard events。提供了几个布尔属性来确定 修改键 是否与您感兴趣的任何目标键一起按下。它们是:
ctrlKey
-- "Control" 键也被按下。
shiftKey
-- "Shift" 键也被按下。
altKey
-- "Alt" 键也被按下。
metaKey
-- "Meta" 键也被按下。
其他重要说明:
- The
which
property is deprecated.
- 使用
keydown
因为Chrome does not fire the keypress
event for known keyboard shortcuts.
一些规范的属性,例如 key
,是 only partly functional in Firefox。
- 您不需要像 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>
如果你和我一样,来这里是为了了解如何检测“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+ò
在意大利语键盘上给出 @
- 每个移位字符都在
e.key
中找到,因为它是移位的对应字符,保留修饰符属性,因此 Shift+5
打印为 Shift+%
,这是有问题的(考虑到 AltGr 行为)。
- 有些组合无论如何都不会触发事件。我在键盘上找到
Ctrl+Shift+9
、Ctrl+Shift+0
、Ctrl+Shift+L
和 Ctrl+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">
如果可读性不是要求and/or您事先知道要检查的组合键,使用event.keyCode而不是event.key
可能更安全。
快速说明。如果您正在检测班次,那么您需要将您正在检查的任何字母大写。 Shift 将通常为小写的字母大写。
if (zEvent.shiftKey && zEvent.key === "T")
对
if (zEvent.ctrlKey && zEvent.key === "t")
if (zEvent.altKey && zEvent.key === "t")
我正在尝试制作脚本 运行 当 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();
}
});
})();
一旦按下一个键,keypress
事件就会被触发。如果您按下多个键,它会在每次按下时触发事件,因此它们被视为独立的按键。
相反,您可以同时使用 keydown
和 keyup
事件来检测多次按键。您可以拥有一个包含 3 个键和一个布尔状态的对象。在 keydown
事件中,如果当前键与对象中的键匹配,则将该键的状态设置为 true
。在 keyup
事件中,您将当前键的状态重置为 false
。如果在最后一次按键时所有 3 个状态都是 true
,则触发事件。
参见 this example 使用 jQuery 实现此逻辑。
更新
Brock 的回答是将修饰键与单个键代码目标结合使用的更好解决方案,因为 ctrlKey
和 altKey
修饰符是组合检测的,而不是独立处理的。例如,如果您想一起检测多个键码,例如 E
和 F
,您需要使用 keydown
和 keyup
来跟踪它们.
参考the W3C spec for keyboard events。提供了几个布尔属性来确定 修改键 是否与您感兴趣的任何目标键一起按下。它们是:
ctrlKey
-- "Control" 键也被按下。shiftKey
-- "Shift" 键也被按下。altKey
-- "Alt" 键也被按下。metaKey
-- "Meta" 键也被按下。
其他重要说明:
- The
which
property is deprecated. - 使用
keydown
因为Chrome does not fire thekeypress
event for known keyboard shortcuts. 一些规范的属性,例如key
,是 only partly functional in Firefox。- 您不需要像 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>
如果你和我一样,来这里是为了了解如何检测“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+ò
在意大利语键盘上给出@
- 每个移位字符都在
e.key
中找到,因为它是移位的对应字符,保留修饰符属性,因此Shift+5
打印为Shift+%
,这是有问题的(考虑到 AltGr 行为)。 - 有些组合无论如何都不会触发事件。我在键盘上找到
Ctrl+Shift+9
、Ctrl+Shift+0
、Ctrl+Shift+L
和Ctrl+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">
如果可读性不是要求and/or您事先知道要检查的组合键,使用event.keyCode而不是event.key
可能更安全。
快速说明。如果您正在检测班次,那么您需要将您正在检查的任何字母大写。 Shift 将通常为小写的字母大写。
if (zEvent.shiftKey && zEvent.key === "T")
对
if (zEvent.ctrlKey && zEvent.key === "t")
if (zEvent.altKey && zEvent.key === "t")