检查一下钥匙是不是坏了?

有没有一种方法可以检测当前 JavaScript 中的键是否处于下行状态?

我知道关键时刻的事,但那不是我想要的。在按下键之后的一段时间,我希望能够检测它是否仍然被按下。

另外。最大的问题似乎是,过了一段时间后,键开始重复,像恶魔一样敲击键盘和敲击键盘。希望只有一个简单的 isKeyDown (key)函数,但如果没有,那么这个问题将需要克服/解决。

163437 次浏览

其他人以前也问过这样的问题(尽管我现在没有看到任何明显的欺骗)。

我认为答案是 keydown事件(和它的孪生 keyup)是所有的信息你得到。重复操作非常牢固地连接到操作系统中,应用程序没有太多机会查询 BIOS 以获得密钥的实际状态。

如果您需要让这个工作正常运行,您可以做的,或者可能必须做的,就是通过编程方式取消键的弹出。基本上,你可以自己评估 keydownkeyup,但是忽略一个 keyup事件,如果它发生在最后一个 keydown之后太快... 或者基本上,你应该延迟你对 keyup的响应足够长的时间,以确保没有另一个 keydown事件后,大约0.25秒的 keyup

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

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

基本上,创建一个长度为要监视的键数的数组。然后使用 document/pages/control 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];
}

这应该能达到你的目的。

有没有一种方法可以检测当前 JavaScript 中的键是否处于下行状态?

不,唯一的可能就是监测每个 keyupkeydown并记住。

过了一段时间后,键开始重复,像恶魔一样敲击键盘和键盘输入。

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

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

除了使用 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*/}
}

This are available on all browser generated event objects, such as those from keydown, keyup, and keypress, so you don't have to use mousemove.

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

我在 Mac 上使用 Chrome 17

/*
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 = ‘ key hide’)。当 Alt 键释放时,标签将消失。使用 jQuery 和 Bootstrap。

我的解决办法是:

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

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

pressedKeys["code of the key"]

如果是真的,就按下按键。

我知道这是一个很老的问题,但是有一个非常轻量级(~ .5 Kb)的 JavaScript 库,它有效地“补丁”了使用 DOMAPI 时键盘事件处理程序的不一致触发。

The library is 钥匙淹死.

下面是一个可操作的代码示例,它只需更改设置侦听器的键就可以很好地实现我的目的:

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();
});

I've incorporated Keydrown into my client-side JavaScript for a proper pause animation in a Red Light Green Light game I'm writing. You can view the entire game 给你. (Note: If you're reading this in the future, the game should be code complete and playable :-D!)

I hope this helps.

最后来到这里检查浏览器是否已经内置了什么东西,但似乎没有。这是我的解决方案(与罗伯特的回答非常相似) :

"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方法只在特殊情况下有效。如果用户使用 alt 标签,或者使用一个按键手势打开一个新的浏览器窗口或标签,那么就会注册一个 keydown,这很好,因为在这一点上,不可能知道这个键是网络应用程序正在监视的东西,还是一个标准的浏览器或操作系统快捷方式。回到浏览器页面,它仍然会认为密钥被持有,尽管它在此期间被释放。或者,当用户使用鼠标切换到另一个选项卡或应用程序,然后在页面外释放某个键时,只需保留某个键即可。

修饰符键(Shift等)可以通过 mousemove等监视,假设有至少一个鼠标交互预期时,选项卡回来,这是经常发生的情况。

对于大多数其他键(除了修饰符,TabDelete,但包括 SpaceEnter) ,监视 keypress将为大多数应用程序工作-按下的键将继续触发。但是,由于 keypress触发的周期性,在重新设置密钥时会有一些延迟。基本上,如果 keypress不继续发射,那么就有可能排除大多数键。虽然我还没有探索如何处理 TabBackspace,但是与修饰符结合起来是非常密不透风的。

我确信有一些库对这个 DOM 弱点进行了抽象,或者一些 DOM 标准更改来解决这个问题,因为这是一个相当古老的问题。

这可以在 Firefox 和 Chrome 中使用。

我需要在本地打开一个特殊的 html 文件(当文件在 Windows 的文件浏览器中被选中时按 Enter) ,要么只是为了查看文件,要么是为了在一个特殊的在线编辑器中编辑它。

所以我想通过按下 Ctrl键或不按键,同时按下 Enter来区分这两个选项。

正如你们从这里的所有答案中了解到的那样,这似乎是不可能的,但是这里有一种模仿这种行为的方法,这种方法对我来说是可以接受的。

事情是这样的:

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

代码还会在出现 keyevents (keyup 和 keydown)时立即关闭它们中的一个。因此,如果在打开文件后按 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;
}

I know it's to late, but I have a lightweight (398 bytes) script that returns if a key is being pressed: 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)

I had good luck detecting if a key was held down by inspecting the keyboard event's repeat财产.

如果在填充文本输入时运行代码段并按住某个键,则应该会看到它反映在输出中。

Presumable you could use these event handlers to save off the repeating key somewhere that other code could check at its own leisure.

const input = document.getElementById('input'),
output = document.getElementById('output');


input.addEventListener('keydown', event => {
if (event.repeat) {
output.value = event.key;
}
});


input.addEventListener('keyup', event => {
output.value = '';
});
<p>
<label for="input">Text input:</label>
<input id="input" />
</p>
<p>
Repeating key = "<output id="output" for="input"></output>"
</p>

KeyboardEvent object describes a single interaction between the user and a key (or combination of a key with modifier keys) on the keyboard

Shift 键 : 是一个布尔值,指示 shift 键是否被按下(true)

KeyboardEvent.ctrlKey: is a boolean value that indicates if the control key was pressed (true) or not (false)

AltKey : 是一个布尔值,指示 alt 键(Option 或 something on macOS)是否按下(true)

例如:

<html>
<head>
<title>shiftKey example</title>


<script type="text/javascript">


function showChar(e){
alert(
"Key Pressed: " + String.fromCharCode(e.charCode) + "\n"
+ "charCode: " + e.charCode + "\n"
+ "SHIFT key pressed: " + e.shiftKey + "\n"
+ "ALT key pressed: " + e.altKey + "\n"
+ "CTRL key pressed: " + e.ctrlKey + "\n"
);
}


</script>
</head>


<body onkeypress="showChar(event);">
<p>Press any character key, with or without holding down
the SHIFT key.<br />
You can also use the SHIFT key together with the ALT key.</p>
</body>
</html>