问题
I have a web app that's running a 60FPS loop forever and I sometimes want to check whether a key is down now. So I made
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)
The problem is that if the user presses control+F to search the page, then when they let go, the find window has focus and thus keyup does not fire. So my app thinks control and F are down forever. So I added this hack for the control key:
// Hack to fix control key being down forever.
window.addEventListener("mousemove", function(e){
if(keydown[17] && !e.ctrlKey) {
keydown[17] = false
}
})
What do I do about it thinking the F key is down forever? I have tried resetting all keys on visibilitychange but it doesn't fire when the user searches.
Here is the demo and source: http://touchbasicapp.com/testkeyup.html
This bug is on windows and mac, Chrome and Safari.
回答1:
Clearing the array when the window loses focus (blur event) is probably your best option.
window.addEventListener("blur", function(e) {
keydown = [];
});
Unfortunately, I don't think there's any guarantee the browser will necessarily fire a blur event in the case of the search interface opening, but they probably should.
回答2:
you need stop the key event for prevent the combinate:
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);
来源:https://stackoverflow.com/questions/57023968/javascript-keep-track-of-which-keys-are-down-accurately