有没有一种方法可以检测JavaScript中当前是否存在某个键?
我知道“ keydown”事件,但这不是我所需要的。按下按键后的一段时间,我希望能够检测到是否仍在按下。
PS最大的问题似乎是在一段时间后,密钥开始重复,触发了诸如恶魔般的keydown和keyup事件。希望只有一个简单的isKeyDown(key)函数,但是如果没有,则需要解决/解决此问题。
Answers:
有没有一种方法可以检测JavaScript中当前是否存在某个键?
不。唯一的可能就是监控每个keyup
与keydown
和记忆。
一段时间后,按键开始重复,触发了按下按键和按下按键等恶性事件。
不应该这样 您肯定会keypress
重复的,在许多浏览器中您也会重复的keydown
,但是如果keyup
重复,那是一个错误。
不幸的是,这并不是一个完全闻所未闻的错误:在Linux,Chromium和Firefox上(当它在GTK +下运行时,在Ubuntu等流行发行版中都运行)都生成重复的keyup-keypress-keydown序列,用于保持键,这与真正快速敲击钥匙的人是无法区分的。
keyup
的事件。
除了使用keyup
和keydown
听众进行跟踪时是关键的下降和备份,也有实际一些属性告诉你,如果某些键下降。
window.onmousemove = function (e) {
if (!e) e = window.event;
if (e.shiftKey) {/*shift is down*/}
if (e.altKey) {/*alt is down*/}
if (e.ctrlKey) {/*ctrl is down*/}
if (e.metaKey) {/*cmd is down*/}
}
这是适用于所有浏览器生成的事件对象,如从keydown
,keyup
和keypress
,所以你不必使用鼠标移动。
我试着用document.createEvent('KeyboardEvent')
和document.createEvent('KeyboardEvent')
寻找e.shiftKey
这样的东西来生成自己的事件对象,但是我没有运气。
我在Mac上使用Chrome 17
我的解决方案:
var pressedKeys = {};
window.onkeyup = function(e) { pressedKeys[e.keyCode] = false; }
window.onkeydown = function(e) { pressedKeys[e.keyCode] = true; }
我现在可以通过检查以下内容来检查是否在脚本中的其他任何位置按下了任何键
pressedKeys["code of the key"]
如果为真,则按下该键。
我不相信有什么像isKeyDown函数,但是您可以编写自己的函数。
基本上,创建一个数组,其长度是要监视的键数。然后使用document / pages / controls keyUp和keyDown事件,以该键的状态更新数组。
然后编写一个检查某个键是否按下并返回布尔值的函数。
var keyEnum = { W_Key:0, A_Key:1, S_Key:2, D_Key:3 };
var keyArray = new Array(4);
function onKeyDown()
{
// Detect which key was pressed
if( key == 'w' )
keyArray[keyEnum.W_Key] = true;
// Repeat for each key you care about...
}
function onKeyUp()
{
// Detect which key was released
if( key == 'w' )
keyArray[keyEnum.W_Key] = false;
// Repeat for each key you care about...
}
function isKeyDown(key)
{
return keyArray[key];
}
那应该完成您想要的。
最终在这里检查浏览器是否已经内置了某些功能,但似乎没有。这是我的解决方案(非常类似于Robert的回答):
"use strict";
const is_key_down = (() => {
const state = {};
window.addEventListener('keyup', (e) => state[e.key] = false);
window.addEventListener('keydown', (e) => state[e.key] = true);
return (key) => state.hasOwnProperty(key) && state[key] || false;
})();
然后,您可以使用键检查是否按下了键is_key_down('ArrowLeft')
。
其他人之前也曾问过这种问题(尽管我现在看不到任何明显的欺骗)。
我认为答案是该keydown
事件(及其孪生子keyup
)就是您所获得的所有信息。重复操作非常牢固地连接到操作系统中,并且应用程序没有太多机会向BIOS查询密钥的实际状态。
您可以做的,或者如果需要进行此工作,可能需要做的是,以编程方式将密钥反跳。本质上,您可以自己评估keydown
,keyup
但keyup
如果事件在最后一次之后过快发生,则可以忽略该事件keydown
;或者本质上,您应该将响应延迟keyup
足够长的时间,以确保不会再出现keydown
0.25秒之类的事件keyup
。
这将涉及使用计时器活动,并记录先前事件的毫秒时间。我不能说这是一个非常吸引人的解决方案,但是...
/*
Tracks what keys are currently down on the keyboard
*/
function keyboard_module(onUpdate){
var kb = {};
var unicode_mapping = {};
document.onkeydown = function(e){
var unicode=e.charCode? e.charCode : e.keyCode
var key = getKey(unicode);
kb[key] = true;
if(onUpdate){
onUpdate(kb);
}
}
document.onkeyup = function(e){
var unicode=e.charCode? e.charCode : e.keyCode
var key = getKey(unicode);
delete kb[key];
if(onUpdate){
onUpdate(kb);
}
}
function getKey(unicode){
if(unicode_mapping[unicode]){
var key = unicode_mapping[unicode];
}else{
var key= unicode_mapping[unicode] = String.fromCharCode(unicode);
}
return key;
}
return kb;
}
function testing(kb){
console.log('These are the down keys', kb);
}
var keyboard = keyboard_module(testing);
....
//somewhere else in the code
if(keyboard['K']){/*do something special */}
以下代码是我正在使用的代码:
var altKeyDownCount = 0;
window.onkeydown = function (e) {
if (!e) e = window.event;
if (e.altKey) {
altKeyDownCount++;
if (30 < altKeyDownCount) {
$('.key').removeClass('hidden');
altKeyDownCount = 0;
}
return false;
}
}
window.onkeyup = function (e) {
if (!e) e = window.event;
altKeyDownCount = 0;
$('.key').addClass('hidden');
}
当用户持续按住Alt键一段时间(约2秒钟)时,将出现一组标签(class =“键隐藏”)。松开Alt键时,标签消失。jQuery和Bootstrap都被使用。
我知道这是一个非常老的问题,但是有一个非常轻便的(〜.5Kb)JavaScript库可以有效地“修补”使用DOM API时键盘事件处理程序的不一致触发。
该库是Keydrown。
这是可操作的代码示例,通过更改设置侦听器的键,可以很好地满足我的目的:
kd.P.down(function () {
console.log('The "P" key is being held down!');
});
kd.P.up(function () {
console.clear();
});
// This update loop is the heartbeat of Keydrown
kd.run(function () {
kd.tick();
});
我已将Keydrown集成到我的客户端JavaScript中,以便在我正在编写的Red Light Green Light游戏中适当地暂停动画。您可以在此处查看整个游戏。(注意:如果您将来要阅读此书,则游戏应该是完整的代码,并且可以玩:-D!)
我希望这有帮助。
我扫描了以上答案,提出的keydown
/ keyup
方法仅在特殊情况下有效。如果用户alt跳开标签,或使用键盘手势打开新的浏览器窗口或标签,则将keydown
注册a,这很好,因为此时无法确定该密钥是否是Web应用程序正在监视的东西,或者是标准的浏览器或操作系统快捷方式。回到浏览器页面,尽管它是同时释放的,但仍然会认为该键已被按住。或者在用户使用鼠标切换到另一个选项卡或应用程序时,只是简单地按住了一些键,然后将其释放到我们的页面之外。
Shift
可以通过mousemove
等方式监视修改键(等),假设在回跳时至少需要进行一次鼠标交互(通常是这种情况)。
对于大多数其他所有按键(除了改性剂,Tab
,Delete
,但包括Space
,Enter
),监控keypress
会为大多数应用-一键按住会继续火。但是由于keypress
触发的周期性,重置密钥会有一些延迟。基本上,如果keypress
不保持触发状态,则可以排除大多数键。与修饰符结合使用时,虽然我还没有探索过与Tab
and的关系,但是它与气密性相当Backspace
。
我敢肯定那里有一些库可以解决这个DOM弱点,或者也许是某些DOM标准更改可以解决这个问题,因为这是一个相当老的问题。
这适用于Firefox和Chrome。
我需要在本地打开一个特殊的html文件(通过Enter
在Windows的文件资源管理器中选择该文件时按),以查看文件或在特殊的在线编辑器中对其进行编辑。
因此,我想通过按住- Ctrl
键或不按住-键来区分这两个选项Enter
。
正如大家从这里的所有答案中都了解到的那样,这似乎不太可能,但是这是一种以我可以接受的方式模仿此行为的方式。
运作方式如下:
如果您Ctrl
在打开文件时按住-key键,则keydown事件将永远不会在javascript代码中触发。但是会触发一个keyup事件(当您最终释放Ctrl
-key时)。该代码捕获了这一点。
一旦其中之一发生,该代码还将关闭键盘事件(键盘事件和键盘事件)。因此,如果Ctrl
在打开文件后按- 键,则不会发生任何事情。
window.onkeyup = up;
window.onkeydown = down;
function up(e) {
if (e.key === 'F5') return; // if you want this to work also on reload with F5.
window.onkeyup = null;
window.onkeyup = null;
if (e.key === 'Control') {
alert('Control key was released. You must have held it down while opening the file, so we will now load the file into the editor.');
}
}
function down() {
window.onkeyup = null;
window.onkeyup = null;
}