【问题标题】:Force keydown event to fire only once per keyCode强制 keydown 事件每个 keyCode 只触发一次
【发布时间】:2021-08-19 13:14:39
【问题描述】:

情况:我有一个 keydown 处理程序和一个 switch 用于按下什么键,这是相当标准的东西,但是当任何键被按住时,keydown 事件会重复触发(而不是而不是在实际按下键时仅一次)。

为什么会出现问题:我想保持keydown 侦听器处于活动状态,即能够检测一次按下多个键,但每个@987654325 只能触发一次事件@。我会想根据上下之间的时间在keyup 上为keyCode 做一些事情,但是由于多次触发,时间被搞砸了。

我尝试过的事情:我目前保留了一个已关闭的keyCodes 列表,并在我的keydown 处理程序中检查这些列表,以防止发生默认行为,如果@ 987654330@ 在我的列表中。但是,该事件仍然经常触发,我担心此解决方案的效率/优雅性。

实际问题:有没有一种好方法可以将keydown 事件的触发限制为在按键被物理按下时触发,或者只监听具体的keyCodes?

【问题讨论】:

  • “即能够检测到同时按下多个键”是什么意思?
  • 例如,按住“y”键,然后同时按住“o”键。这里排除了去掉keydown事件,keyup后重新添加的方案。

标签: javascript jquery


【解决方案1】:

在 keydown 处理程序中,检查键是否与最后处理的键相同。如果是,请尽早退出。在 keyup 时,忘记处理的最后一个键。

例如:

var lastEvent;
var heldKeys = {};

window.onkeydown = function(event) {
    if (lastEvent && lastEvent.keyCode == event.keyCode) {
        return;
    }
    lastEvent = event;
    heldKeys[event.keyCode] = true;
};

window.onkeyup = function(event) {
    lastEvent = null;
    delete heldKeys[event.keyCode];
};​

Demo here(点击“结果”面板并按键)。

【讨论】:

    【解决方案2】:

    定义一个布尔值来记录按键是否被按下。在按键事件中将其设置为 true。让你的主循环检查值是否为真并处理事件,并将按下的键设置为假。如果键被释放(最初为假),则有另一个布尔值来记录。如果 key-up 事件触发,请将其设置为已释放。如果“释放”值也为真,则仅将按键值设置为真(在按键事件中)。

    【讨论】:

    • 这是一个很好的答案。我唯一可能要补充的是,我将定义一个对象数组,以便在按下每个键码时存储布尔值,并且在该对象中将是 [{ "43": true}, ... ] 然后只需按照上面的建议删除该键码即可。
    • 这实际上是我现在正在做的事情,如果不清楚,请见谅。我将保存“向下”键码并在键上删除它们。我对任何可能比每秒检查几次 keyCodes 列表更有效的替代方法感兴趣。
    【解决方案3】:

    这是我认为您想要实现的示例:jsFiddle Example

    目前,CTRL+B 组合是唯一检测到的组合。只需按一些数字即可获取活动日志。当按键已经被按下时,它会检测到保持动作。

    【讨论】:

      【解决方案4】:

      这是一个更简洁的版本,不易出错。当前键是否是最后一个键并不重要,因为如果 keyup 事件尚未触发,则它仍处于 keydown 状态。

      var heldKeys = {};
      
      window.onkeydown = function(event) {
          if (heldKeys[event.keyCode]) {
              return;
          }
          heldKeys[event.keyCode] = true;
      };
      
      window.onkeyup = function(event) {
          heldKeys[event.keyCode] = false;
      };​
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多