skip to Main Content

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


  1. 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, the keydown 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

    <script>
      function handle(ev, el) {
        let isCapsLockOn = ev.getModifierState('CapsLock');
        document.getElementById('message').innerText = isCapsLockOn ? 'CAPS LOCK' : '.';
        let log = document.getElementById('log');
        log.innerText = new Date() + 'n' + log.innerText;
      }
    </script>
    

    HTML

    <body>
      <input onkeyup="handle(event, this)" />
      <div id="message" role="alert"></div>
      <div id="log"></div>
    </body>
    

    Snippet

        <body>
          <input onkeyup="handle(event, this)" />
          <div id="message" role="alert"></div>
          <div id="log"></div>
        </body>
        
            <script>
          function handle(ev, el) {
            let isCapsLockOn = ev.getModifierState('CapsLock');
            document.getElementById('message').innerText = isCapsLockOn ? 'CAPS LOCK' : '.';
            let log = document.getElementById('log');
            log.innerText = new Date() + 'n' + log.innerText;
          }
        </script>

    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:

    <body>
        <input id="inputField" type="text" onkeyup="handle(event)" />
        <div id="message" role="alert"></div>
        <div id="log"></div>
    </body>
    
    <script>
      function handle(event) {
        let target = document.getElementById('inputField');
        let isCapsLockOn = event.getModifierState && event.getModifierState( 'CapsLock' );
        if (target.value.charCodeAt() >= 65 && target.value.charCodeAt() <= 90 && !event.shiftKey) isCapsLockOn = true;
        if (target.value.charCodeAt() >= 97 && target.value.charCodeAt() <= 122 && event.shiftKey) isCapsLockOn = true;
        document.getElementById('message').innerText = isCapsLockOn ? 'CAPS LOCK' : '.';
        let log = document.getElementById('log');
        log.innerText = new Date() + 'n' + log.innerText;
      }
    </script>
    Login or Signup to reply.
  2. you can try this solution

    <!DOCTYPE html>
    <html>
    <head>
      <title>Caps Lock Detection</title>
    </head>
    <body>
    
    <input type="text" id="inputField" placeholder="Type something...">
    <div id="capsLockWarning" style="display: none; color: red;">Caps Lock is on!</div>
    
    <script>
      document.getElementById("inputField").addEventListener("keypress", function(event) {
        // Check if Caps Lock key is pressed
        var capsLockOn = event.getModifierState && event.getModifierState("CapsLock");
    
        // Check if the pressed key is a letter and is uppercase when Caps Lock is off
        if (event.key && event.key.match(/[a-z]/i) && event.key === event.key.toUpperCase() && !capsLockOn) {
          document.getElementById("capsLockWarning").style.display = "block";
        } else {
          document.getElementById("capsLockWarning").style.display = "none";
        }
      });
    </script>
    
    </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search