keypress 事件为什么监听不到方向键?

Newb.梓轩 阅读 74

我在写一个用键盘控制的小游戏,想用 keypress 事件监听方向键(上下左右),但发现根本没反应。查了下文档说 keypress 只对能产生字符的按键有效,那方向键这种功能键该怎么监听才对?

我试过换成 keydown 事件,确实可以捕获到,但不确定是不是最佳做法。有没有什么兼容性要注意的?比如下面这样写:

document.addEventListener('keypress', (e) => {
  if (e.key === 'ArrowUp') {
    console.log('up');
  }
});
我来解答 赞 15 收藏
二维码
手机扫码查看
2 条解答
司徒誉琳
问题在于 keypress 事件不支持方向键。改用 keydown 事件监听方向键就对了。代码如下:
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowUp') {
console.log('up');
}
});
点赞
2026-03-24 06:01
钰欣 ☘︎
keypress 只对能产生字符的按键有效,方向键、功能键、修饰键都不会触发它,这是浏览器的事件设计,文档里确实没说错。

用 keydown 是对的,方向键、Esc、Tab 这些功能键只能靠 keydown 或 keyup 来监听。

兼容性方面,现在主流浏览器都支持 e.key 这个属性,返回 ArrowUpArrowDown 这种字符串,语义化做得很好。如果要兼容很老的 IE(IE9 以下),就得用 e.keyCode 了,方向键对应的 keyCode 是 37-40,不过现在基本没人管这个了。

还有个事要注意:keydown 会重复触发。比如你按住方向键不放,事件会一直触发直到松开。如果做移动控制,这通常是想要的效果,但如果你只需要触发一次(比如按一下扣一次血),可以考虑 keyup,或者在 keydown 里加个标志位来防抖。

改完大概长这样:

document.addEventListener('keydown', (e) => {
switch(e.key) {
case 'ArrowUp':
console.log('up');
// 这里写你的移动逻辑
break;
case 'ArrowDown':
console.log('down');
break;
case 'ArrowLeft':
console.log('left');
break;
case 'ArrowRight':
console.log('right');
break;
}
});


如果你同时需要兼容旧浏览器,可以这样写:

document.addEventListener('keydown', (e) => {
const key = e.key || e.keyCode;
if (key === 'ArrowUp' || key === 38) {
// 上
}
});


顺带提醒一下,做游戏的时候最好在 keydown 里加个 e.preventDefault(),防止方向键触发页面滚动,虽然现代浏览器一般不会,但如果你的游戏是全屏的或者页面本身有滚动,这个细节能省掉不少调试时间。
点赞
2026-03-17 01:03