How do you tell if caps lock is on using JavaScript?

Viewed 122459

How do you tell if caps lock is on using JavaScript?

One caveat though: I did google it and the best solution I could find was to attach an onkeypress event to every input, then check each time if the letter pressed was uppercase, and if it was, then check if shift was also held down. If it wasn't, therefore caps lock must be on. This feels really dirty and just... wasteful - surely there's a better way than this?

31 Answers

In jQuery,

$('#example').keypress(function(e) { 
    var s = String.fromCharCode( e.which );
    if ( s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey ) {
        alert('caps is on');
    }
});

Avoid the mistake, like the backspace key, s.toLowerCase() !== s is needed.

You can give it a try.. Added a working example. When focus is on input, turning on caps lock makes the led go red otherwise green. (Haven't tested on mac/linux)

NOTE: Both versions are working for me. Thanks for constructive inputs in the comments.

OLD VERSION: https://jsbin.com/mahenes/edit?js,output

Also, here is a modified version (can someone test on mac and confirm)

NEW VERSION: https://jsbin.com/xiconuv/edit?js,output

NEW VERSION:

function isCapslock(e) {
  const IS_MAC = /Mac/.test(navigator.platform);

  const charCode = e.charCode;
  const shiftKey = e.shiftKey;

  if (charCode >= 97 && charCode <= 122) {
    capsLock = shiftKey;
  } else if (charCode >= 65 && charCode <= 90
    && !(shiftKey && IS_MAC)) {
    capsLock = !shiftKey;
  }

  return capsLock;
}

OLD VERSION:

function isCapslock(e) {
  e = (e) ? e : window.event;

  var charCode = false;
  if (e.which) {
    charCode = e.which;
  } else if (e.keyCode) {
    charCode = e.keyCode;
  }

  var shifton = false;
  if (e.shiftKey) {
    shifton = e.shiftKey;
  } else if (e.modifiers) {
    shifton = !!(e.modifiers & 4);
  }

  if (charCode >= 97 && charCode <= 122 && shifton) {
    return true;
  }

  if (charCode >= 65 && charCode <= 90 && !shifton) {
    return true;
  }

  return false;
}

For international characters, additional check can be added for the following keys as needed. You have to get the keycode range for characters you are interested in, may be by using a keymapping array which will hold all the valid use case keys you are addressing...

uppercase A-Z or 'Ä', 'Ö', 'Ü', lowercase a-Z or 0-9 or 'ä', 'ö', 'ü'

The above keys are just sample representation.

You can detect caps lock using "is letter uppercase and no shift pressed" using a keypress capture on the document. But then you better be sure that no other keypress handler pops the event bubble before it gets to the handler on the document.

document.onkeypress = function ( e ) {
  e = e || window.event;
  var s = String.fromCharCode( e.keyCode || e.which );
  if ( (s.toUpperCase() === s) !== e.shiftKey ) {
    // alert('caps is on')
  }
}

You could grab the event during the capturing phase in browsers that support that, but it seems somewhat pointless to as it won't work on all browsers.

I can't think of any other way of actually detecting caps lock status. The check is simple anyway and if non detectable characters were typed, well... then detecting wasn't necessary.

There was an article on 24 ways on this last year. Quite good, but lacks international character support (use toUpperCase() to get around that).

We use getModifierState to check for caps lock, it's only a member of a mouse or keyboard event so we cannot use an onfocus. The most common two ways that the password field will gain focus is with a click in or a tab. We use onclick to check for a mouse click within the input, and we use onkeyup to detect a tab from the previous input field. If the password field is the only field on the page and is auto-focused then the event will not happen until the first key is released, which is ok but not ideal, you really want caps lock tool tips to display once the password field gains focus, but for most cases this solution works like a charm.

HTML

<input type="password" id="password" onclick="checkCapsLock(event)" onkeyup="checkCapsLock(event)" />

JS

function checkCapsLock(e) {
  if (e.getModifierState("CapsLock")) {
    console.log("Caps");
  }
}

https://codepen.io/anon/pen/KxJwjq

This jQuery-based answer posted by @user110902 was useful for me. However, I improved it a little to prevent a flaw mentioned in @B_N 's comment: it failed detecting CapsLock while you press Shift:

$('#example').keypress(function(e) { 
    var s = String.fromCharCode( e.which );
    if (( s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey )
    ||  ( s.toLowerCase() === s && s.toUpperCase() !== s && e.shiftKey )) {
        alert('caps is on');
    }
});

Like this, it will work even while pressing Shift.

How about using getModifierState()

The getModifierState() method returns true if the specified modifier key was pressed, or activated.

You can use it like:

function checkIfCapsLockIsOn(event) {
  var capsLockIsOn = event.getModifierState("CapsLock");
  console.log("Caps Lock activated: " + capsLockIsOn);
}

This will simply check if CapsLock is ON or OFF and show it in console. You can change the way the function you want to work.

And then use this function on keydown or keyup for example.

<input type="text" onkeydown="checkIfCapsLockIsOn(event)">

it is late i know but, this can be helpfull someone else.

so here is my simpliest solution (with Turkish chars);

function (s,e)
{
    var key = e.htmlEvent.key;

    var upperCases = 'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZXWQ';
    var lowerCases = 'abcçdefgğhıijklmnoöprsştuüvyzxwq';
    var digits = '0123456789';

    if (upperCases.includes(key))
    {
        document.getElementById('spanLetterCase').innerText = '[A]';
    }

    else if (lowerCases.includes(key))
    {
        document.getElementById('spanLetterCase').innerText = '[a]';
    }

    else if (digits.includes(key))
    {
        document.getElementById('spanLetterCase').innerText = '[1]';
    }

    else
    {
        document.getElementById('spanLetterCase').innerText = '';
    }
}

So I found this page and didn't really like the solutions I found so I figured one out and am offering it up to all of you. For me, it only matters if the caps lock is on if I'm typing letters. This code solved the problem for me. Its quick and easy and gives you a capsIsOn variable to reference whenever you need it.

let capsIsOn=false;
let capsChecked=false;

let capsCheck=(e)=>{
    let letter=e.key;
    if(letter.length===1 && letter.match(/[A-Za-z]/)){
        if(letter!==letter.toLowerCase()){
          capsIsOn=true;
          console.log('caps is on');
        }else{
          console.log('caps is off');
        }
        capsChecked=true;
        window.removeEventListener("keyup",capsCheck);
    }else{
      console.log("not a letter, not capsCheck was performed");
    }

}

window.addEventListener("keyup",capsCheck);

window.addEventListener("keyup",(e)=>{
  if(capsChecked && e.keyCode===20){
    capsIsOn=!capsIsOn;
  }
});

Related