当keyup事件(对于另一个键)被触发时,keydown(重复)会中断

时间:2011-04-30 12:51:19

标签: javascript events keypress keydown onkeyup

这有点奇怪,所以我认为我要么缺少一些明显的东西,要么这是在浏览器中如何实现这些事件的缺陷。

首先总结一个示例场景,在提供一个孤立的案例示例之前,这个问题就出现了;

箭头键用于移动播放器(因为只要在页面的任何位置按键,就会触发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事件中的重复。

我尝试了各种各样的事情,包括在事件处理函数中使用返回false,返回true,尝试按键而不是keydown,保存键状态并在按钮的keystate仍为true时继续移动,但它是什么所有归结为当keyup被解雇时,任何积极传播的keydown事件都被杀死。我已阅读JavaScript Madness: Keyboard Events并且我没有看到任何关于这种特定行为的内容。

这是关键事件实施的设计缺陷,还是我遗漏了什么?我在Chrome,IE和&amp ;;中观察到了同样的行为。 Firefox浏览器。

有任何建议或意见吗?

2 个答案:

答案 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”以及所需的任何键控代码在其中的位置。我用它来防止重复输入游戏。希望这会有所帮助!