Detecting combination keypresses (Control, Alt, Shift)?

If you, like me, came here to find out how to detect the combination of the "Alt Gr" key with a letter key, then the properties like for example event.altKey cannot be used for this, since there is no event.AltGrKey property.

In that case you can use

event.getModifierState('AltGraph')

For more details see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState


Refer to the W3C spec for keyboard events. Several boolean attributes are provided to determine if modifier keys were pressed in conjunction with whatever target key you are interested in. They are:

  • ctrlKey     -- The "Control" key was also pressed.
  • shiftKey   -- The "Shift" key was also pressed.
  • altKey       -- The "Alt" key was also pressed.
  • metaKey     -- The "Meta" key was also pressed.

Other important notes:

  1. The which property is deprecated.
  2. Use keydown because Chrome does not fire the keypress event for known keyboard shortcuts.
  3. Some spec'd properties, such as key, are only partly functional in Firefox.
  4. You do not need to wrap your code in an anonymous function like that for Tampermonkey (or Greasemonkey or most userscript engines). Scope protection is automatically provided.

So, your code would become:

document.addEventListener ("keydown", function (zEvent) {
    if (zEvent.ctrlKey  &&  zEvent.altKey  &&  zEvent.key === "e") {  // case sensitive
        // DO YOUR STUFF HERE
    }
} );

Run this handy demo (updated now that key has full support):

var targArea = document.getElementById ("keyPrssInp");
targArea.addEventListener ('keydown',  reportKeyEvent);

function reportKeyEvent (zEvent) {
    var keyStr = ["Control", "Shift", "Alt", "Meta"].includes(zEvent.key) ? "" : zEvent.key + " ";
    var reportStr   =
        "The " +
        ( zEvent.ctrlKey  ? "Control " : "" ) +
        ( zEvent.shiftKey ? "Shift "   : "" ) +
        ( zEvent.altKey   ? "Alt "     : "" ) +
        ( zEvent.metaKey  ? "Meta "    : "" ) +
        keyStr + "key was pressed."
    ;
    $("#statusReport").text (reportStr);

    //--- Was a Ctrl-Alt-E combo pressed?
    if (zEvent.ctrlKey  &&  zEvent.altKey  &&  zEvent.key === "e") {  // case sensitive
        this.hitCnt = ( this.hitCnt || 0 ) + 1;
        $("#statusReport").after (
            '<p>Bingo! cnt: ' + this.hitCnt + '</p>'
        );
    }
    zEvent.stopPropagation ();
    zEvent.preventDefault ()
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p><label>Press keys in here:<input type="text" value="" id="keyPrssInp"></label>
</p>
<p id="statusReport"></p>

The keypress event is fired as soon as a key has been pressed. If you are pressing multiple keys, it will fire the event for each press, so they are considered independent key presses.

Instead, you can use both the keydown and keyup events to detect multiple key presses. You can have an object that contains the 3 keys and a boolean state. On the keydown event, if the current key matches a key in the object, you set the state to true for that key. On the keyup event, you reset the state for the current key to false. If all 3 states are true at the time of the last key press, then fire the event.

See this example that achieves this logic using jQuery.

Update Brock's answer is a better solution for you using modifier keys in combination with a single key code target, as the ctrlKey and altKey modifiers are detected in combination, not handled independently. If you want to detect multiple key codes like, E and F together, for example, you'd need to keep track of them using keydown and keyup as per above.