检查钥匙是否关闭?

Dan*_*ore 82 javascript keyboard input

有没有办法检测JavaScript当前是否存在关键字?

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

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

Dev*_*ode 124

除了使用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*/}
}
Run Code Online (Sandbox Code Playgroud)

这是适用于所有浏览器生成的事件对象,如从keydown,keyupkeypress,这样你就不必使用鼠标移动.

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

我在Mac上使用Chrome 17

  • “这在所有浏览器生成的事件对象上都可用”。嗯,不是*所有*浏览器事件。看起来只有“KeyboardEvent”和“MouseEvent”类型的事件以及它们的后代(如“TouchEvent”)才具有与按键相关的属性,如“altKey”。我希望 `FocusEvent` 可能有它,但是没有。 (2认同)

bob*_*nce 64

有没有办法检测JavaScript当前是否存在关键字?

不.唯一的可能就是监控每个keyupkeydown和记忆.

一段时间后,密钥开始重复,启动keydown和keyup事件,如恶魔.

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

不幸的是,它不是一个完全闻所未闻的错误:在Linux,Chromium和Firefox上(当它在GTK +下运行时,它在流行的发行版中,如Ubuntu)都会为持有的密钥生成重复的keyup-keypress-keydown序列,这是不可能区别于真正快速锤击钥匙的人.

  • 你先生是绅士和学者.Ubuntu上的Chromium和Firefox是我的主要开发环境,因此可以准确地解释我一直看到的问题.希望它会变得更好,否则计时器黑客解决方案可能是唯一的解决方法. (14认同)
  • 8年之后,情况仍然如此吗?这个答案可能需要更新. (4认同)
  • 是的,在这方面没有任何进展令人沮丧.请参阅https://bugs.launchpad.net/ubuntu/+bug/369880.我正在编写一个浏览器游戏,目前我的解决方法是坚持修改键(shift,ctrl等),它们根本不重复. (3认同)
  • 解析帮助:(Linux &&(Chromium ||(Firefox && GTK +))) (3认同)
  • 不,它可以通过缺少相应的"keyup"事件来区分它们与真正重复的按键. (2认同)
  • @mako是不是他解释了什么?:那个'keyup`事件也被发出了? (2认同)
  • GTK+ 错误现在已修复,但其余部分仍然存在。 (2认同)
  • 如果有人正在寻找的话,MouseEvent 具有 shiftKey 属性。因此,实际上可以通过除 keydown 之外的其他方式来检查修饰键。 (2认同)
  • @BrunoFreire 哇,太糟糕了。我打算建议监听“模糊”事件(显然是在“窗口”上,而不是“文档”上),并在收到时记录所有键已被释放。根据我的经验,这似乎可以可靠地处理丢失的按键事件。但我不知道如何处理相应的 keydown 之前的 keyup,这似乎无法正确处理。 (2认同)

小智 38

我的解决方案

var keys = {};
window.onkeyup = function(e) { keys[e.keyCode] = false; }
window.onkeydown = function(e) { keys[e.keyCode] = true; }
Run Code Online (Sandbox Code Playgroud)

我现在可以检查是否在脚本中的任何其他位置按下了任何键

keys["code of the key"]
Run Code Online (Sandbox Code Playgroud)

如果是,则按下该键.

  • 由于键已经是一个函数,因此不同的变量名可能更好. (2认同)
  • 这不适用于在所有情况下检测 Alt 键是否按下。 (2认同)
  • 请小心 Mac 上的“cmd-tab”或 Windows 上的“ctrl-tab”等内容。它将触发按键,然后切换窗口,当它们回来时,它永远不会触发按键(因为浏览器没有专注于接收该按键事件) (2认同)

Fal*_*tar 11

我不相信有任何像isKeyDown函数,但你可以编写自己的函数.

基本上,创建一个数组,其长度是您要监视的键数.然后使用documents/pages/controls keyUp和keyDown事件,使用该键的状态更新数组.

然后编写一个函数来检查某个键是否关闭并返回一个bool.

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];
}
Run Code Online (Sandbox Code Playgroud)

那应该完成你想要的.

  • 这不是一个好的解决方案,因为你会写越来越多的ifs.一个"keyList = {};" 作为对象接受"keyList [key] = true;" 不需要枚举或限制,因为它使用字符串索引/属性,适用于所有键. (3认同)

ant*_*tam 7

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

"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;
})();
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用 来检查是否按下了某个键is_key_down('ArrowLeft')