检查键是否已关闭?

IT技术 javascript input keyboard
2021-03-06 15:57:11

有没有办法检测 JavaScript 中的某个键当前是否已关闭?

我知道“keydown”事件,但这不是我需要的。按下键后的一段时间,我希望能够检测它是否仍然被按下。

PS 最大的问题似乎是在一段时间后,键开始重复,像恶魔一样触发 keydown 和 keyup 事件。希望只有一个简单的 isKeyDown(key) 函数,但如果没有,则需要克服/解决此问题。

6个回答

除了使用keyupkeydown听众进行跟踪时是关键的下降和备份,也实际一些属性告诉你,如果某些键下降。

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*/}
}

这是适用于所有浏览器生成的事件对象,如从keydownkeyupkeypress,所以你不必使用鼠标移动。

我尝试使用document.createEvent('KeyboardEvent')and生成我自己的事件对象document.createEvent('KeyboardEvent')并寻找e.shiftKey等等,但我没有运气。

我在 Mac 上使用 Chrome 17

涂料答案,正是我来这里寻找的。谢谢!
2021-04-19 15:57:11
我在新旧浏览器中都使用这个,甚至 HTA 的
2021-05-06 15:57:11
实际上,如果您的意思是 Shift,那么您不应该在 keyup 上寻找 e.shiftKey。在例如 onclick 上使用 e.shiftKey 代替。
2021-05-07 15:57:11
嘿@RobertoSepúlvedaBravo 罗伯特似乎在下一个答案中回答了您的问题。;)
2021-05-09 15:57:11
当某个数字目前下降时,有没有办法实现这个答案?我试过 if (e.keyCode==49) {console.log("1 is down");} 但不起作用:(
2021-05-14 15:57:11

有没有办法检测 JavaScript 中的某个键当前是否已关闭?

不。唯一的可能性是监控每个keyupkeydown并记住。

一段时间后,键开始重复,像恶魔一样触发 keydown 和 keyup 事件。

它不应该。你肯定会得到keypress重复,在许多浏览器中你也会得到重复keydown,但如果keyup重复,那就是一个错误。

不幸的是,这并不是一个完全闻所未闻的错误:在 Linux、Chromium 和 Firefox 上(当它在 GTK+ 下运行时,它在流行的发行版中,例如 Ubuntu)都为保持的键生成重复的 keyup-keypress-keydown 序列,这是不可能与某人快速敲击钥匙区分开来的。

先生是君子,是学者。Ubuntu 上的 Chromium 和 Firefox 是我的主要开发环境,因此准确地解释了我一直看到的问题。希望它会变得更好,否则计时器黑客解决方案可能是唯一的解决方法。
2021-04-18 15:57:11
不,这可以由他们缺乏相应的从真正的重复按键区别开来keyup的事件。
2021-04-25 15:57:11
是的,令人沮丧的是,这方面没有任何进展。参见bugs.launchpad.net/ubuntu/+bug/369880我正在编写一个浏览器游戏,我目前的解决方法是坚持使用根本不重复的修饰键(shift、ctrl 等)。
2021-04-29 15:57:11
8 年后,情况仍然如此吗?这个答案可能需要更新。
2021-05-04 15:57:11
解析帮助:(Linux && (Chromium || (Firefox && GTK+))))
2021-05-16 15:57:11

我的解决方案:

var pressedKeys = {};
window.onkeyup = function(e) { pressedKeys[e.keyCode] = false; }
window.onkeydown = function(e) { pressedKeys[e.keyCode] = true; }

我现在可以通过检查来检查是否在脚本中的其他任何地方按下了任何键

pressedKeys["code of the key"]

如果为真,则按下该键。

小心 Mac 上的“cmd-tab”或 Windows 上的“ctrl-tab”。它会按下键,然后切换窗口,当它们回来时它永远不会触发键(因为浏览器没有专注于接收该键事件)
2021-05-01 15:57:11
这非常适合检测上/下/左/右
2021-05-10 15:57:11
在所有情况下,这不适用于检测 Alt 键是否按下。
2021-05-12 15:57:11
由于键已经是一个函数,不同的变量名可能会更好。
2021-05-15 15:57:11

我不相信有类似 isKeyDown 函数的东西,但您可以编写自己的函数。

基本上,创建一个数组,其长度是您要监视的键数。然后使用文档/页面/控件 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];
}

那应该完成你想要的。

这很好,确实是解决方案的一部分,但它并没有解决我遇到的重复键盘问题。参见 bobince 的回答。
2021-04-30 15:57:11
这不是一个好的解决方案,因为您将编写越来越多的 if。一个“keyList = {};” 作为一个对象接受“keyList[key] = true;” 不需要枚举或限制,因为它使用字符串索引/属性并适用于所有键。
2021-05-07 15:57:11

在这里结束是为了检查浏览器是否已经内置了一些东西,但似乎没有。这是我的解决方案(与罗伯特的回答非常相似):

"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')