检查钥匙是否关闭?

时间:2009-12-01 20:17:23

标签: javascript input keyboard

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

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

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

13 个答案:

答案 0 :(得分:113)

除了使用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的事件对象,因此您不必使用mousemove。

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

我在Mac上使用Chrome 17

答案 1 :(得分:59)

  

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

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

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

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

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

答案 2 :(得分:33)

我的解决方案:

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

我现在可以通过检查

来检查脚本中的任何其他位置是否按下了任何键
keys["code of the key"]

如果是,则按下该键。

答案 3 :(得分: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];
}

这应该能达到你想要的效果。

答案 4 :(得分:1)

其他人之前已经提出过这样的问题(虽然我现在没有看到任何明显的愚蠢行为)。

我认为答案是keydown事件(及其双keyup)是您获得的所有信息。重复操作非常牢固地连接到操作系统,并且应用程序没有太多机会向BIOS查询密钥的实际状态。

如果你需要让这个工作,你可以做什么,也许还有,就是以编程方式去除反弹键。从本质上讲,您可以自己评估keydownkeyup但忽略keyup事件,如果它在上一次keydown之后过快发生......或者基本上,您应该推迟对keyup的响应时间足够长,以确保在keydown的0.25秒之后没有其他keyup事件。

这将涉及使用计时器活动,并记录先前事件的毫秒时间。我不能说这是一个非常有吸引力的解决方案,但是......

答案 5 :(得分:1)

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

答案 6 :(得分:1)

结束此处以检查浏览器是否已内置了某些内容,但似乎没有。这是我的解决方案(非常类似于罗伯特的回答):

"use strict";

let is_key_down = (() => {
    let 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')检查是否按下了某个键。

答案 7 :(得分:0)

查看this回答,并使用onkeyuponkeydownHere是有关这些事件的更具体的信息。

答案 8 :(得分:0)

我知道这是一个非常古老的问题,但是有一个非常轻量级的(〜.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中,以便在我正在编写的红灯绿灯游戏中获得适当的暂停动画。您可以查看整个游戏here。 (注意:如果您将来阅读此内容,游戏应该是代码完整且可玩的:-D!)

我希望这会有所帮助。

答案 9 :(得分:0)

我查看了以上答案,并且提出的keydown / keyup方法仅在特殊情况下有效。如果用户alt跳开标签,或使用键盘手势打开新的浏览器窗口或标签,则将注册keydown,这很好,因为此时无法确定该密钥是否是某些东西。该Web应用正在监视,或者是标准的浏览器或操作系统快捷方式。回到浏览器页面,尽管它是同时释放的,但仍然会认为该键已被按住。或者,只是在用户使用鼠标切换到另一个选项卡或应用程序,然后将其释放到我们的页面之外时简单地按住某些键即可。

可以通过Shift等监视修饰键(mousemove等),假设在回跳时至少需要一个鼠标交互,这是常见的情况。

对于大多数所有其他键(修饰符TabDelete,但包括SpaceEnter),监视keypress适用于大多数应用程序-按住的键将继续发射。不过,由于keypress触发的周期性,重置密钥会有一些延迟。基本上,如果keypress不保持触发状态,则可以排除大多数键。尽管我还没有探索如何处理TabBackspace,但将其与修饰符结合起来还是很密封的。

我敢肯定,有一个库可以针对此DOM弱点进行抽象,或者可能是某些DOM标准更改解决了这个问题,因为这是一个相当老的问题。

答案 10 :(得分:0)

这在Firefox和Chrome中有效。

我需要在本地打开一个特殊的html文件(在Windows的文件浏览器中选择该文件时,通过按Enter),或者只是为了查看文件,或者是在特殊的在线编辑器中对其进行编辑

因此,我想通过按住Ctrl的同时按住Enter键来区分这两个选项。

正如大家从这里的所有答案中都了解到的那样,这似乎不太可能,但这是一种以我可以接受的方式模仿这种行为的方式。

工作方式如下:

如果您在打开文件时按住Ctrl键,那么keydown事件将永远不会在javascript代码中触发。但是会触发一个keyup事件(当您最终释放Ctrl键时)。该代码捕获了这一点。

一旦其中一个事件发生,代码也将关闭键盘事件(键盘事件和键盘事件)。因此,如果在文件打开后按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;
}

答案 11 :(得分:-1)

我知道为时已晚,但我有一个轻量级(398 字节)脚本,该脚本在按下某个键时返回:https://github.com/brunoinds/isKeyPressed

if (KeyPressing.isKeyPressed(13)){ //Pass the keyCode integer as parameter
     console.log('The Enter key is being pressed!')
  }else{
     console.log('The Enter key is NOT being pressed!')
  }

你甚至可以设置一个时间间隔来检查按键是否被按下:

setInterval(() => {
    if (KeyPressing.isKeyPressed(13)){
        console.log('The Enter key is being pressed!')
    }else{
        console.log('The Enter key is NOT being pressed!')
    }
  }, 1000) //Update data every 1000ms (1 second)

答案 12 :(得分:-2)

$('#mytextbox').keydown(function (e) {
            if (e.keyCode == 13) {
                if (e.altKey) {
                    alert("alt is pressed");
                }
            }
 });

如果按alt + Enter,您将看到警报。