I want to detect CapsLock in an input. I used getModifierState
which I found here:
function handle(ev, el) {
//if (ev.isComposing || ev.keyCode === 229) return; // for firefox
let isCapsLockOn = ev.getModifierState('CapsLock');
document.getElementById('message').innerText = isCapsLockOn ? 'CAPS LOCK' : '.';
let log = document.getElementById('log');
log.innerText = new Date() + 'n' + log.innerText;
}
<html>
<body>
<input onkeydown="handle(event, this)" />
<div id="message"></div>
<div id="log"></div>
</body>
</html>
When pressing CapsLock in the input, I expect it to show or hide "CAPS LOCK". But what actually happens is it flickers on and off, or shows the message but opposite to whether the key is actually on.
One can also see from the "log" element that the event is firing twice. I don’t know why, but that’s probably the reason.
I tried in firefox, chromium and edge, with the same result. So I doubt (?) it’s a misbehaving browser extension. I’m using a standard qwerty keyboard. For firefox I also added if (ev.isComposing || ev.keyCode === 229) return;
as per this.
How can I fix this?
UPDATE
Thanks to the commenters below, it seems like this should work. So in the spirit of the "Works For Me" idea, I guess this one just "Doesn’t Work For Me".
2
Answers
The reason you’re seeing the event fired twice is probably because you are listening the
keydown
event. When you press and hold down the key, thekeydown
event gets triggered multiple times.A better solution would be to use the
keyup
event instead, which fires after the key is pressed and released:JavaScript
HTML
Snippet
I’ve found that
getModifierState('CapsLock')
is not consistent across some browsers and operating systems, so i tried looking for the char values, and worked for me, try it out:you can try this solution