1

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.

Curtis
  • 2,486
  • 5
  • 40
  • 44
  • 1
    Check for the window blur event maybe? Also, keep in mind Cmd + F for macOS users (`e.metaKey`), plus other things that could switch focus. – Alexander O'Mara Jul 14 '19 at 01:47
  • thanks that works! I updated the example with window.addEventListener('blur', function(e){keydown=[]}) So it's foolproof now? – Curtis Jul 14 '19 at 01:54

2 Answers2

2

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.

Alexander O'Mara
  • 58,688
  • 18
  • 163
  • 171
0

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);