JavaScript - 检测按键

JavaScript - Detecting Key Presses

我正在使用 addEventListener 检查用户的按键, 但也有一些问题。

这是我的代码:

// get key presses

var keys = {
  up: false,
  down: false,
  left: false,
  right: false
}

function keyUpdate(keyEvent, down) {
  // down is a boolean, whether the key event is keydown (true) or keyup (false)
  switch (keyEvent.keyCode) {

    case 38:
      keys.up = down;
      break;

    case 40:
      keys.down = down;
      break;

    case 37:
      keys.left = down;
      break;

    case 39:
      keys.right = down;
      break;
  }
}

document.addEventListener("keydown", function(event) {
  keyUpdate(event, true);
});

document.addEventListener("keyup", function(event) {
  keyUpdate(event, false);
});

这段代码有两个问题:

为什么我会有这些问题?

编辑:看了答案,我得出的结论是我的 browser/computer 有问题。它似乎只发生在箭头键上。正如莫比乌斯所说,一次激活两个以上的键确实没有必要。

使用按键事件,这样它只会在用户按下某个键时执行,而不是在他们按下时执行。

document.addEventListener("keypress", function(event) {
    keyUpdate(event, true);
});

document.addEventListener("keyup", function(event) {
    keyUpdate(event, false);
});

我可以使用您提供的代码同时获得两个键来显示。我修改了示例以显示数据和图形表示。如果您没有看到多个键同时工作,则可能是浏览器限制。

我在 OSX

上使用 Chrome 53

// get key presses

var keys = {
  up: false,
  down: false,
  left: false,
  right: false
}

function keyUpdate(keyEvent, down) {
  // down is a boolean, whether the key event is keydown (true) or keyup (false)
  keyEvent.preventDefault(); // prevent screen from going crazy while i press keys.
  console.log(keyEvent.keyCode)
  switch (keyEvent.keyCode) {

    case 87: // W key.
    case 38:  // up key.
      keys.up = down;
      var key = document.querySelector('.up');
      if (down){
        key.classList.add('pressed');
      } else {
        key.classList.remove('pressed');
      }
      break;
      
    case 83: // S key
    case 40: // down key
      keys.down = down;
      var key = document.querySelector('.down');
      if (down){
        key.classList.add('pressed');
      } else {
        key.classList.remove('pressed');
      }
      break;

    case 65: // A key
    case 37: // left arrow.
      keys.left = down;
      var key = document.querySelector('.left');
      if (down){
        key.classList.add('pressed');
      } else {
        key.classList.remove('pressed');
      }
      break;
    case 68:
    case 39: // right arrow.
      keys.right = down;
      var key = document.querySelector('.right');
      if (down){
        key.classList.add('pressed');
      } else {
        key.classList.remove('pressed');
      }
      break;
    default:
      if (down){
         keys[keyEvent.keyCode] = down;
      } else if (keyEvent.keyCode in keys){
        delete keys[keyEvent.keyCode];
      }
  }
  var text = JSON.stringify(keys, null, 4);
  document.querySelector('.code').innerHTML = text;
}

document.addEventListener("keydown", function(event) {
  keyUpdate(event, true);
});

document.addEventListener("keyup", function(event) {
  keyUpdate(event, false);
});


document.querySelector('.code').innerHTML = JSON.stringify(keys, null, 4);
h3 {
  text-align: center;
  font-family: sans-serif;
  text-decoration: underline;
  font-weight: normal;
}
.keys {
  width: 150px;
  margin: 0 auto;
}
.rows {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items : center;
}

.key{
  flex: 1;
  width: 50px;
  max-width: 50px;
  height: 50px;
  background-color: #eee;
  text-align:center;
  line-height: 50px;
  border-radius: 3px;
  border: 1px solid #aaa;
  transition: all .2s ease;
  color : #555;
  font-size: 20px;
  font-weight: bold;
}

.pressed{
  color : #ddd;
  background-color: #aaa;
  border: 1px solid #eee;
}

.columns{
  display: flex;
  flex-direction: row;
  justify-content: space-arround;
}

.code {
  background-color: #efefef;
  border: 1px solid #aaa;
}
<h3> click here to start capturing keyboard input</h1>
<div class="keys rows">
  <div class="key up">↑</div>
  <div class="columns">
    <div class="key left">←</div>
        <div class="key down">↓</div>
    <div class="key right">→</div>
  </div>
</div>
<pre class="code">
</pre>

编辑:在进一步检查中,一次只能使用两个键的限制似乎仅限于箭头键。我已经更新了示例,以显示除箭头键之外的任何当前按下的按键代码。您会注意到您可以添加两个以上。

edit 2 我使用 dvorak 键盘布局,并没有意识到我把 WASD 键设置错了。它们现在适用于标准 QWERTY 布局。