JavaScript中检测箭头键的按下

610

如何检测箭头键被按下?我使用了以下方法来查找:

function checkKey(e) {
    var event = window.event ? window.event : e;
    console.log(event.keyCode)
}

虽然它对于其他按键有效,但对于箭头键无效(可能是因为浏览器默认情况下应该在这些键上进行滚动)。

22个回答

931

箭头键仅由onkeydown触发,而不是onkeypress

键码如下:

  • 左箭头 = 37
  • 上箭头 = 38
  • 右箭头 = 39
  • 下箭头 = 40

26
有些浏览器会为箭头键触发 keypress 事件,但你说得对,keydown 总是适用于箭头键。 - Tim Down
4
如果您按下“%”,则还会获得keyCode 37。 - xorcus
12
不,使用“keydown”事件可以得到53。而使用“keypress”则可以获得37,两者是不同的。 - user578895
1
当你按住箭头键时,@1nfiniti onkeyup不会考虑到keydown事件的重复调用。 - pmrotule
4
@MrCroft - 或者监听 onkeyup 事件并在那里停止事件。现实情况是,您不应该使用Javascript修改UI行为。 - user578895
显示剩余6条评论

296

在按键弹起和按下时调用函数。对于每个按键,都有不同的代码。

document.onkeydown = checkKey;

function checkKey(e) {

    e = e || window.event;

    if (e.keyCode == '38') {
        // up arrow
    }
    else if (e.keyCode == '40') {
        // down arrow
    }
    else if (e.keyCode == '37') {
       // left arrow
    }
    else if (e.keyCode == '39') {
       // right arrow
    }

}

4
第二行代码的作用是什么? - eshellborn
22
为了澄清,“e || window.event”意味着如果“e”是一个已定义的值,它将成为“||”表达式的结果。如果“e”未定义,“window.event”将成为“||”表达式的结果。因此,这基本上是以下两行代码的简写形式:e = e ? e : window.event;或者: if (typeof(e) === "undefined") { e = window.event; } - Michael Calvin
28
这是为了让它在旧版本的IE(IE9之前)上运行,因为事件没有传递到处理程序函数中。 - Mark Rhodes
17
请注意,keyCode是一个数字,最好使用===。 - alexrogers
14
@ketan 的意思是 keyCode 是一个数字,应该像 keyCode === 32 这样检查,而不是 keyCode == '32'keyCode === '32' - Joel Peltonen
显示剩余8条评论

280

event.key === "ArrowRight"...

最新且更清晰:使用event.key。不再有任意的数字代码!如果你正在转译或知道你的用户都在现代浏览器上,使用这个吧!

node.addEventListener('keydown', function(event) {
    const key = event.key; // "ArrowRight", "ArrowLeft", "ArrowUp", or "ArrowDown"
});

冗长处理:

switch (event.key) {
    case "ArrowLeft":
        // Left pressed
        break;
    case "ArrowRight":
        // Right pressed
        break;
    case "ArrowUp":
        // Up pressed
        break;
    case "ArrowDown":
        // Down pressed
        break;
}

现代开关处理:

const callback = {
    "ArrowLeft"  : leftHandler,
    "ArrowRight" : rightHandler,
    "ArrowUp"    : upHandler,
    "ArrowDown"  : downHandler,
}[event.key]
callback?.()

注意: 旧属性 (.keyCode.which) 已被弃用。

"w", "a", "s", "d" 代表方向,使用 event.code

为了支持使用非qwerty / 英语键盘布局的用户,您应该改用event.code。这将保持物理按键位置,即使结果字符更改。

event.key在Dvorak上是,,在Azerty上是z,这会导致您的游戏无法玩。

const {code} = event
if (code === "KeyW") // KeyA, KeyS, KeyD

最好还能允许键位重映射,这样无论玩家处境如何都会受益。

P.S. event.code 对于箭头键是相同的

key Mozilla 文档

code Mozilla 文档

支持的浏览器


14
感谢您使用key而不是已被弃用的keyCode。我们将继续优化和改进我们的代码以提供更好的用户体验。 - v010dya
13
MDN 的注释:Internet Explorer、Edge(16 及更早版本)和 Firefox(36 及更早版本)使用“Left”、“Right”、“Up”和“Down”代替“ArrowLeft”、“ArrowRight”、“ArrowUp”和“ArrowDown”。 - Simon
1
由于event.keyCode已被弃用,因此这应该是被接受的答案。 - relief.melone
我非常喜欢现代的开关处理方式。 - Iglesias Leonardo
1
我猜测 event.key === "ArrowRight" 不是在进行字符串比较以检查单个按键。有人能确认一下吗? - jdhildeb

102

可能是最简洁的表述:

document.onkeydown = function(e) {
    switch (e.keyCode) {
        case 37:
            alert('left');
            break;
        case 38:
            alert('up');
            break;
        case 39:
            alert('right');
            break;
        case 40:
            alert('down');
            break;
    }
};

Demo演示(感谢用户Angus Grant):http://jsfiddle.net/angusgrant/E3tE6/

这应该可以跨浏览器使用。如果有任何无法使用的浏览器,请留言。

有其他方法可以获取按键代码(例如e.which、e.charCode和window.event,而不是e),但它们不是必需的。您可以在http://www.asquare.net/javascript/tests/KeyCode.html上尝试大多数方法。 请注意,event.keycode在Firefox的onkeypress中不起作用,但在onkeydown中起作用。


5
我不得不查阅terse的定义,然后我(活泼地)推测tersest是一种不正确的变形。唉,我承认:我的担忧是可驳斥的 - ashleedawg

22

对于像箭头键这样的非可打印按键,请使用 keydown 而不是 keypress

function checkKey(e) {
    e = e || window.event;
    alert(e.keyCode);
}

document.onkeydown = checkKey;

我找到的最好的JavaScript键盘事件参考资料(例如胜过quirksmode)在这里:http://unixpapa.com/js/key.html


现在keypress已被标记为过时。 - Dmitry Koroliov

20

由于keyCode现已被弃用,转而使用key

document.onkeydown = function (e) {
    switch (e.key) {
        case 'ArrowUp':
            // up arrow
            break;
        case 'ArrowDown':
            // down arrow
            break;
        case 'ArrowLeft':
            // left arrow
            break;
        case 'ArrowRight':
            // right arrow
    }
};

18

我相信最近的方法应该是:

document.addEventListener("keydown", function(event) {
  event.preventDefault();
  const key = event.key; // "ArrowRight", "ArrowLeft", "ArrowUp", or "ArrowDown"
  switch (key) { // change to event.key to key to use the above variable
    case "ArrowLeft":
      // Left pressed
      <do something>
      break;
    case "ArrowRight":
      // Right pressed
      <do something>
      break;
    case "ArrowUp":
      // Up pressed
      <do something>
      break;
    case "ArrowDown":
      // Down pressed
      <do something>
      break;
  }
});

假设开发者希望代码在页面的任何位置都可以激活,并且客户端应忽略任何其他按键。如果希望包括由此处理程序捕获的按键仍然处于活动状态,则应删除event.preventDefault(); 行。


9
这是一个示例实现:

以下是一个示例实现:

var targetElement = $0 || document.body;

function getArrowKeyDirection (keyCode) {
  return {
    37: 'left',
    39: 'right',
    38: 'up',
    40: 'down'
  }[keyCode];
}

function isArrowKey (keyCode) {
  return !!getArrowKeyDirection(keyCode);
}

targetElement.addEventListener('keydown', function (event) {
  var direction,
      keyCode = event.keyCode;

  if (isArrowKey(keyCode)) {
    direction = getArrowKeyDirection(keyCode);

    console.log(direction);
  }
});

我遇到了“$0未定义”的问题。以下代码可以解决这个问题:var targetElement = typeof $0 !== 'undefined' ? $0 : document.body; 或者直接使用这个代码:var targetElement = document.body;,都是可以的。 - papo

9
function checkArrowKeys(e){
    var arrs= ['left', 'up', 'right', 'down'], 
    key= window.event? event.keyCode: e.keyCode;
    if(key && key>36 && key<41) alert(arrs[key-37]);
}
document.onkeydown= checkArrowKeys;

2
arrs 放在函数外面不值得吗?没必要每次调用都重新创建它。 - Grief

8
这是我完成它的方法:
var leftKey = 37, upKey = 38, rightKey = 39, downKey = 40;
var keystate;
document.addEventListener("keydown", function (e) {
    keystate[e.keyCode] = true;
});
document.addEventListener("keyup", function (e) {
    delete keystate[e.keyCode];
});

if (keystate[leftKey]) {
//code to be executed when left arrow key is pushed.
}
if (keystate[upKey]) {
//code to be executed when up arrow key is pushed.
}
if (keystate[rightKey]) {
//code to be executed when right arrow key is pushed.
}
if (keystate[downKey]) {
//code to be executed when down arrow key is pushed.
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接