这有点奇怪,所以我想我要么遗漏了一些明显的东西,要么这是浏览器中这些事件实现方式的一个缺陷。
在提供一个孤立的案例之前,首先让我总结一下这个问题出现的一个示例场景-示例;
箭头键用于移动播放器(因为任何时候点击页面上的任意一个键都会触发handleKeyDown函数)。同样,只要释放一个键,就会触发另一个函数(handleKeyUp)。
当你(玩家)按住左键时,handleKeyDown函数会被反复触发(诚然,我认为这违背了你的预期和名字的含义,但尽管如此,这是所有浏览器的正常行为,我相信你知道)。
所以会发生这样的事情:玩家拿着一个方向朝那个方向走;然后他们按下一个数字键(对于热键项目),同时按下方向继续走。这里发生的事情是,当你释放热键项目的数字键时,重复的玩家移动就会停止!
我已经为这种行为写了一个非常小的孤立示例:
<html>
<head>
<script type='text/javascript' src='jquery-1.5.1.min.js'></script>
<script type='text/javascript'>
var log = {};
var keyState = {};
var keyCount = {'down': 0, 'up': 0};
window.addEventListener('keydown', handleKeyDown, false);
window.addEventListener('keyup', handleKeyUp, false);
function handleKeyDown (e)
{
keyState[e.keyCode] = true;
keyCount.down++;
log.prepend(" ["+e.keyCode+"] ");
return false;
}
function handleKeyUp (e)
{
keyState[e.keyCode] = false;
keyCount.down++;
return true;
}
$(function(){log = $('#log');});
</script>
</head>
<body>
<div id='debug'></div>
<div id='log'></div>
</body>
你也可以在这里尝试一下:
http://sikosoft.net/keys.html
按下页面上的任意键,您将看到keyCode出现在页面上。当您按住该键时,键代码会重复一次又一次。
在仍然按住初始键的同时按下不同的键时,行为会变得奇怪。在释放最近的键时,重复从第一个键停止。有趣的是,如果您尝试该示例并按住一个键,然后按住第二个键,但不是释放第二个键,而是释放第一个键:第二个键确实会继续重复。
因此,似乎发生的事情是,当keyup事件被激发时,它似乎终止了在较早的键上激发的keydown事件中的重复。
我尝试过各种各样的方法,从在两个事件处理函数中使用returning false,返回true,尝试使用keypress而不是keydown,保存按键状态,如果按钮的keystate仍然为true,则继续移动,但归根结底,当keyup被触发时,任何主动传播的keydown事件都会被杀死。我已经通读了JavaScript Madness: Keyboard Events,我没有看到任何关于这种特定行为的东西。
这是key-events实现的设计缺陷,还是我遗漏了什么?我在Chrome、IE和Firefox中观察到了同样的行为。
有什么建议或建议吗?
发布于 2011-04-30 21:01:16
这就是操作系统/环境的工作方式,因此也是浏览器的工作方式。
在浏览器中的另一个键上的keyup之后,keydown重复不应该继续触发,因为它在其他任何地方都不会这样做。打开记事本、vim、pico或您使用的任何文本编辑器,并执行相同的事件序列。您将看到,在快捷键之后,您按下的第一个键不会一直打印新的字母。这就是这些东西在操作系统中设计的方式,结果就是它们被传播到编辑器和浏览器等的方式。
发布于 2019-01-18 01:46:55
这是我的键盘输入系统。您可以在这里看到如何提取重复键供您自己使用。它将允许您注意到按键,而不是像另一个错误假设的答案那样依赖于操作系统。
var down = [140]; //make an array to cover all the keypresses you should need with a normal keyboard
document.addEventListener('keydown', function(event) {
if (down[event.keyCode]){
return;
} else {
//do the normal things you do when you get key presses
down[event.keyCode]=true;
}
}, true);
document.addEventListener('keyup', function(event) {
down[event.keyCode]=false;
//do the normal things you do when you get key releases
}, true);你只需要检查数组"down“和你想要的任何关键代码在其中的位置。我用它来防止游戏输入的重复键。希望这能有所帮助!
发布于 2021-10-05 14:39:49
对于未来的读者,你可以尝试这个。
let keys = {};
document.onkeydown = e => {
if (!keys[e.code]) {
keys[e.code] = true;
}
};
document.onkeyup = e => (keys[e.code] = false);
move = () => {
if (keys["ArrowLeft"]) {
console.log("ArrowLeft")
}
if (keys["ArrowRight"]) {
console.log("ArrowRight")
}
if (keys["ArrowDown"]) {
console.log("ArrowDown")
}
if (keys["ArrowUp"]) {
console.log("ArrowUp")
}
};
setInterval(move, 100);
https://stackoverflow.com/questions/5841853
复制相似问题