【问题标题】:In Javascript, how do I tell if a user is pressing two keys at the same time?在 Javascript 中,如何判断用户是否同时按下两个键?
【发布时间】:2010-01-09 04:10:55
【问题描述】:

在 Javascript 中,我如何判断用户是否同时按下两个键?

例如,我在屏幕中间画了一个圆圈。我想在用户按住向上箭头的同时向右移动它,同时用户按住向右箭头。那部分工作很容易。如果用户同时按住向上和向右箭头,我想将圆圈沿对角线向上和向右移动。

对于基本的 Javascript 事件处理来说,这看起来不太可能,但肯定有人已经想出了一个变通/破解/改进的方法。

【问题讨论】:

  • 你是如何用Javascript在屏幕中间画圆的?如果您使用某些库,请指定它,密钥处理应在该库内完成。
  • 我使用了 Raphael [raphaeljs.com],它是一个 svg 库。我认为它不提供任何按键输入功能。

标签: javascript events keyboard


【解决方案1】:

这是你在概念上需要做的(我猜这被称为伪代码):

从这样的开始:

var PIXEL_DELTA  = 10; // Distance to move in pixels

var leftPressed  = 0,
    upPressed    = 0,
    downPressed  = 0,
    rightPressed = 0;

然后在每个keydown 事件上,测试按下的键是否为leftup 等,并将其变量从0 转换为PIXEL_DELTA

在每个keyup 事件上,运行相同的测试并将正确的变量转回0

然后,在您的移动代码中(真实代码):(此代码改编自 Crescent Fresh 的精彩示例):

function move() {
  var dot = document.getElementById('dot'),
      deltaX = rightPressed - leftPressed,
      deltaY = downPressed - upPressed;

  if(deltaX) {
    dot.style.left = (parseInt(dot.style.left, 10) || 0) + deltaX + 'px';
  }

  if (deltaY) {
    dot.style.top = (parseInt(dot.style.top, 10) || 0) + deltaY + 'px';
  }
}

浏览器将(应该)为每个键触发一个单独的keydown/keyup 事件,即使它们是“同时”按下的。

工作示例

Crescent Fresh 整理了一个full example on JSBin。请务必访问editable version 以及玩代码。

【讨论】:

  • 是的,但我会使用数字并在0(您的错误)和n(您的正确)之间切换,其中n 是像素增量。移动代码不需要测试布尔值,而只需做一些基本的算术。非伪代码:jsbin.com/iloxi
  • @Crescent,我喜欢它。如果您不想发布自己的答案,我会更新我的答案,但您确实应该这样做,因为它是一个很好的解决方案并且您有一个有效的演示。
  • @DN: 做我的客人,你成功了。
【解决方案2】:

Javascript 有 onkeydown 和 onkeyup 事件。您可以简单地为左箭头拨动一下 onkeydown,然后为向上箭头拨动一点。在 keyup 上,将相应的位拨回。

var leftPressed,
    upPressed,
    rightPressed,
    downPressed;

var milli = 100;

window.addEventListener('onkeydown', function(e) {
    switch(e.keycode) {
        case 37: //left
            leftPressed = true;
        case 38: //up
            upPressed = true;
        case 39: //right
           rightPressed = true;
        case 40: //down
            downPressed = true;
        default:
            break;
    }
});

window.addEventListener('onkeyup', function(e) {
    switch(e.keycode) {
        case 37: //left
            leftPressed = false;
        case 38: //up
            upPressed = false;
        case 39: //right
           rightPressed = false;
        case 40: //down
            downPressed = false;
        default:
            break;
    }

});

function moveCircle() {
    if(leftPressed && !rightPressed) {
        // move left
    }
    if(rightPressed && !leftPressed) {
        // move right
    }
    if(upPressed && !downPressed) {
        // move up
    }
    if(downPressed && !upPressed) {
        // move down
    }
}

setInterval(moveCircle, milli);

【讨论】:

  • 我认为您的一般想法会起作用,但我认为这段代码行不通。如果按键被按住,按键消息会重复发送。而且我不想将圆圈移回keyup。我想停止移动它。
  • 你说得对,我可能混淆了 onkeydown 和 onkeypress。但是,onkeyup部分是停止移动的方向。在左下角,dx 变为 -1。解除后,dx +1 再次变为 0。
  • @seanmonstar:你仍然有 keydown 事件自动重复的问题。
  • Chrome/Safari/IE 似乎不会触发箭头键的按键事件。
  • keydown 是正确的事件,正如@BlueWaldo 指出的那样。我认为您最好将您感兴趣的键的向上/向下状态存储为布尔值。
【解决方案3】:

也许您可以通过跟踪每个键的 keydown 和 keyup 事件来做到这一点,并且您会知道是否同时按住两个键。

示例伪代码:

var keydown = {};

function onkeydown(event) {
   keydown[event.key] = true;
}

function onkeyup(event) {
   keydown[event.key] = false;
}

// in some function at some other places

if (keydown['up'] && keydown['right']) {
  move_diagonal('up', 'right');
}
elseif (keydown['up'] && keydown['left']) {
  move_diagonal('up', 'left');
}
elseif .. blah blah

【讨论】:

    【解决方案4】:

    Javascript 键盘事件在 keypress 和 keydown 时触发,但不包含用于确定是否同时按下其他键的附加键掩码信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-07
      • 2016-01-03
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      相关资源
      最近更新 更多