JavaScript 准确跟踪哪些键按下

JavaScript keep track of which keys are down accurately

我有一个网络应用程序,它 运行 永远是一个 60FPS 循环,有时我想检查一下键是否已按下。所以我做了

var keydown = []
window.addEventListener("keydown", function(e){keydown[e.keyCode]=true})
window.addEventListener("keyup", function(e){keydown[e.keyCode]=false})
function loop() {
    if(keydown[17]) console.log("Control is down.")
    if(keydown[71]) console.log("F is down.")
}
setInterval(loop, 16)

问题是,如果用户按下 control+F 来搜索页面,那么当他们放手时,查找 window 有焦点,因此 keyup 不会触发。所以我的应用程序认为 control 和 F 永远关闭。所以我为控制键添加了这个 hack:

// Hack to fix control key being down forever.
window.addEventListener("mousemove", function(e){
    if(keydown[17] && !e.ctrlKey) {
        keydown[17] = false
    }
})

如果我认为 F 键永远处于关闭状态,我该怎么办?我已尝试重置 visibilitychange 上的所有键,但它不会在用户搜索时触发。

这是演示和来源:http://touchbasicapp.com/testkeyup.html

此错误存在于 windows 和 mac、Chrome 和 Safari 上。

当 window 失去焦点(模糊事件)时清除数组可能是您的最佳选择。

window.addEventListener("blur", function(e) {
    keydown = [];
});

不幸的是,我不认为有任何保证浏览器一定会在搜索界面打开时触发模糊事件,但他们可能应该。

您需要停止按键事件以防止组合:

var keydown = []
window.addEventListener("keydown", function (e) {
 e.preventDefault();
 keydown[e.keyCode] = true;
});
window.addEventListener("keyup", function (e) {
 e.preventDefault();
 keydown[e.keyCode] = false;
});

function loop() {
 var comb = "";
 if (keydown[17]) comb += "CTRL";
 if (keydown[70]) {
  if (keydown[17]) comb += "+";
  comb += "F";
 }
 if ((keydown[17]) || (keydown[70])) console.log("I press " + comb);
}
setInterval(loop, 50);