这有点奇怪,所以我认为我要么缺少一些明显的东西,要么这是在浏览器中如何实现这些事件的缺陷。
首先总结一个示例场景,在提供一个孤立的案例示例之前,这个问题就出现了;
箭头键用于移动播放器(因为只要在页面的任何位置按键,就会触发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>
你也可以在这里试试:
按页面上的任意键,您将看到页面上出现keyCode。按住键时,键码会一遍又一遍地重复。
当初始键仍然被按住时,按下另一个键时,行为变得古怪。在释放该最近的密钥时,重复从第一个密钥停止。有趣的是,如果您尝试该示例并按住一个键,然后按住第二个键,但不释放第二个键,则释放第一个键:第二个键继续重复。
所以看起来似乎是在触发keyup事件时,它似乎终止了在早期密钥上触发的keydown事件中的重复。
我尝试了各种各样的事情,包括在事件处理函数中使用返回false,返回true,尝试按键而不是keydown,保存键状态并在按钮的keystate仍为true时继续移动,但它是什么所有归结为当keyup被解雇时,任何积极传播的keydown事件都被杀死。我已阅读JavaScript Madness: Keyboard Events并且我没有看到任何关于这种特定行为的内容。
这是关键事件实施的设计缺陷,还是我遗漏了什么?我在Chrome,IE和&amp ;;中观察到了同样的行为。 Firefox浏览器。
有任何建议或意见吗?
答案 0 :(得分:5)
这就是操作系统/环境的工作方式,因此也就是浏览器的工作方式。
keydown重复不应该在浏览器中另一个键的keyup之后继续触发,因为它在其他任何地方都不会那样。打开记事本,或vim,或pico,或您使用的任何文本编辑器,并执行相同的事件序列。你会看到在键盘之后,你按下的第一个键不会继续打印新的字母。这就是在操作系统中设计这些东西的方式,结果就是它们被传播到编辑器和浏览器等的方式。
答案 1 :(得分:0)
这是我的键盘输入系统。您可以在此处查看如何提取重复密钥以供自己使用。它将使您注意到按住的键,而不必依赖操作系统作为错误地假定的另一个答案。
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”以及所需的任何键控代码在其中的位置。我用它来防止重复输入游戏。希望这会有所帮助!