首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当触发keyup事件(用于另一个键)时,keydown (重复)中断

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

Stack Overflow用户
提问于 2011-04-30 20:51:19
回答 3查看 5.2K关注 0票数 2

这有点奇怪,所以我想我要么遗漏了一些明显的东西,要么这是浏览器中这些事件实现方式的一个缺陷。

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

箭头键用于移动播放器(因为任何时候点击页面上的任意一个键都会触发handleKeyDown函数)。同样,只要释放一个键,就会触发另一个函数(handleKeyUp)。

当你(玩家)按住左键时,handleKeyDown函数会被反复触发(诚然,我认为这违背了你的预期和名字的含义,但尽管如此,这是所有浏览器的正常行为,我相信你知道)。

所以会发生这样的事情:玩家拿着一个方向朝那个方向走;然后他们按下一个数字键(对于热键项目),同时按下方向继续走。这里发生的事情是,当你释放热键项目的数字键时,重复的玩家移动就会停止!

我已经为这种行为写了一个非常小的孤立示例:

代码语言:javascript
复制
<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中观察到了同样的行为。

有什么建议或建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-30 21:01:16

这就是操作系统/环境的工作方式,因此也是浏览器的工作方式。

在浏览器中的另一个键上的keyup之后,keydown重复不应该继续触发,因为它在其他任何地方都不会这样做。打开记事本、vim、pico或您使用的任何文本编辑器,并执行相同的事件序列。您将看到,在快捷键之后,您按下的第一个键不会一直打印新的字母。这就是这些东西在操作系统中设计的方式,结果就是它们被传播到编辑器和浏览器等的方式。

票数 7
EN

Stack Overflow用户

发布于 2019-01-18 01:46:55

这是我的键盘输入系统。您可以在这里看到如何提取重复键供您自己使用。它将允许您注意到按键,而不是像另一个错误假设的答案那样依赖于操作系统。

代码语言:javascript
复制
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“和你想要的任何关键代码在其中的位置。我用它来防止游戏输入的重复键。希望这能有所帮助!

票数 0
EN

Stack Overflow用户

发布于 2021-10-05 14:39:49

对于未来的读者,你可以尝试这个。

代码语言:javascript
复制
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);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5841853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档