I was doing tests to detect the keyboard keys, it occurred to me to save it in an array and add the keys in the order in which they are held down. For example, if you keep "w" and "a", the array would be ["w", "a"]. The problem occurs when you hold "w" and then "SHIFT". When you stop holding "w", the key is not removed from the array.
Note: to replicate the problem, first hold down the "w" and while holding it down then press the "SHIFT". Then release the "w" while holding down the "SHIFT".
let keysPressed = [];
document.addEventListener('keydown', (event) => {
if (!keysPressed.includes(event.key)) {
keysPressed.push(event.key)
}
});
document.addEventListener('keyup', (event) => {
const keyIndex = keysPressed.indexOf(event.key);
if (keyIndex !== -1) {
keysPressed.splice(keyIndex, 1)
}
});
function update() {
if (keysPressed.length > 0) {
document.getElementById('status').innerHTML = `Pressed keys: ${keysPressed.join(', ')}<br>Last pressed key: ${keysPressed[keysPressed.length - 1]}`;
} else {
document.getElementById('status').textContent = 'No keys pressed'
}
requestAnimationFrame(update)
}
requestAnimationFrame(update)
body {
font-family: Arial, sans-serif;
}
.status {
font-size: 1.5em;
color: green;
}
<body>
<h2>Hold a key pressed</h2>
<p class="status" id="status">No key pressed</p>
</body>
2
Answers
Yes. You pressed ‘w’ and released ‘W’.
If you want to be transparent to shift, remove also ‘w’.
If you want to interact at key level, not string level, that is, just register any pressed key (whatever the modifier are when it is pressed), and then unregister any key (whatever the modifiers are when it is released), then you should focus on key code, not key.
Or you could do both. If you want to give a "string" name to the key for display, while being able to match a release with a previous press, you should keep the
key
for display, andcode
for register. That is probably the best thing to do (rather than playing withlower
,upper
, that would work only if the preconception of what modifier do happen to be true. After all, a user could have mapped "Shift+W" on "Q". Not to mention other modifiers).Note that the usage of two arrays that are kept synchronous (we add a key code at the end of
keysCodes
when and only when we add a key at the end ofkeysPressed
. We remove element at positionkeyIndex
fromkeyCodes
when and only when we remove element at positionkeyIndex
ofkeysPressed
is inelegant. That assumption that they will stay synchronous for ever is not abusive, as long as nobody else interact withe neither of those arrays, but if you later try to do something clever with those arrays, well, it is not ideal when you need to trust future coders (even when future coders is you) not to forget that those two arrays must be kept synchronous.Generally speaking that is why I prefer "arrays of pairs" than "pairs of arrays".
So, that should probably be done differently to use objects, classes, arrays of arrays, or something, and search for object by one of the fields when needed. But I wanted to keep as close as possible to your implementation.
this is not a problem this is just how
KeyEvent.key
works cuz it returns symbol which was pressed or released and in you example you just did:but if you use
KeyEvent.code
this will look like:also
KeyEvent.key
will return symbol according to current selected language on device so you even can switch languages during session and it will return differentKeyEvent.key
even if you press the same key