这有点奇怪,所以我想我要么遗漏了一些明显的东西,要么这是这些事件在浏览器中实现方式的缺陷。
在提供一个孤立的案例之前,让我先总结一下这个问题提出的一个示例场景;
箭头键用于移动播放器(因为只要在页面上的任何位置按下键就会触发 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,保存按键状态以及如果按钮的按键状态仍然为真,则继续移动,但这一切都失败了to 是当 keyup 被触发时,任何积极传播的 keydown 事件都会被杀死。我已经阅读了JavaScript Madness: Keyboard Events,但我没有看到任何关于这种特定行为的信息。
这是实现关键事件的设计缺陷,还是我遗漏了什么?我在 Chrome、IE 和 Firefox 中观察到了同样的行为。
有什么建议或意见吗?