What is the most sensible way to detect if a key (e.g. F) is pressed without any modifier key (e.g. Ctrl, Alt, Alt Gr)?
Do you have to explicitly consider every single modifier key?
KeyboardEvent: ctrlKey property, altKey property, AltGraph key value
window.addEventListener("keydown", (event) => {
if (!event.ctrlKey && !event.altKey && event.key !== "AltGraph" && event.key === "f") {
doSomething();
}
});
KeyboardEvent: getModifierState() method
window.addEventListener("keydown", (event) => {
if (!event.getModifierState("Control") && !event.getModifierState("Alt") && !event.getModifierState("AltGraph") && event.key === "f") {
doSomething();
}
});
2
Answers
getModifierState()
is probably what you need. Just create a list of keys needed to check, and the corresponding function:Unfortunately, yes.
Why?
The DOM UI Events specification describes (๐, ๐) that modifier state must be stored independent of
keydown
events:โฆbut this state representation is not exposed to the JavaScript runtime. So that leaves you with the responsibility to iterate every modifier key value that matters to your program’s code.
Getting a list of modifier keys
How can you get a list of these modifier key values? Unfortunately โย there’s also no JavaScript API that exposes a valid enum list for iteration. ๐
However, a modifier key table is included (๐, ๐) in the UI Events key specification, and โย at the time I write this answer โย the values include:
"Alt"
"AltGraph"
"CapsLock"
"Control"
"Fn"
"FnLock"
"Meta"
"NumLock"
"ScrollLock"
"Shift"
"Symbol"
"SymbolLock"
There’s also a separate table which lists legacy modifier key values:
"Hyper"
"Super"
Detecting (the absence of) modifier keys
As noted in your question, you can use the KeyboardEvent:
getModifierState()
method (spec (๐, ๐)) to check each modifier key. Here’s a working example based on the details in your question:Code in the TypeScript Playground
Notes about the code above:
Array.prototype.some()
stops iterating immediately after the first truthy value is returned by the callback argument. You can optimize the number of iteration cycles by ordering the more commonly-used modifier keys to the beginning of the array. In the example, I ordered some according to my intuitions, but you can modify these based on data collected from your users.