Check Ctrl / Shift / Alt keys on 'click' event

JavascriptJqueryHtmlfirefox3.6

Javascript Problem Overview


How could I identify which Ctrl / Shift / Alt keys are pressed in the following code ?

$("#my_id").click(function() {
    if (<left control key is pressed>) { alert("Left Ctrl"); }
    if (<right shift and left alt keys are pressed>) { alert("Right Shift + Left Alt"); }
});

Javascript Solutions


Solution 1 - Javascript

Well you this wont work in all browsers just IE 8. Microsoft implemented the ability to determine which (right/left) key was pressed. Here is a link http://msdn.microsoft.com/en-us/library/ms534630(VS.85).aspx

I also found this wonder article about keypress, keyup, keydown event in browsers. http://unixpapa.com/js/key.html

$('#someelement').bind('click', function(event){ 

    if(event.ctrlKey) {
      if (event.ctrlLeft) {
        console.log('ctrl-left'); 
      }
      else {
        console.log('ctrl-right');
      }
    }
    if(event.altKey) {
      if (event.altLeft) {
        console.log('alt-left'); 
      }
      else {
        console.log('alt-right');
      }
    }
    if(event.shiftKey) {
      if (event.shiftLeft) {
        console.log('shift-left'); 
      }
      else
      {
        console.log('shift-right');
      }
    }
  }); 

Solution 2 - Javascript

$('#someelement').bind('click', function(event){
   if(event.ctrlKey)
      console.log('ctrl');
   if(event.altKey)
      console.log('alt');
   if(event.shiftKey)
      console.log('shift');

});

I don't know if it's possible to check for left/right keys within a click event, but I don't think it's possible.

Solution 3 - Javascript

e.originalEvent.location returns 1 for left key and 2 for right key. Therefore you can detect which modifier key is pressed like following. Hope this will help you.

var msg = $('#msg');
$(document).keyup(function (e) {
      if (e.keyCode == 16) {
          if (e.originalEvent.location == 1)
              msg.html('Left SHIFT pressed.');
          else
              msg.html('Right SHIFT pressed.');
      } else if (e.keyCode == 17) {
          if (e.originalEvent.location == 1)
              msg.html('Left CTRL pressed.');
          else
              msg.html('Right CTRL pressed.');
      } else if (e.keyCode == 18) {
          if (e.originalEvent.location == 1)
              msg.html('Left ALT pressed.');
          else
              msg.html('Right ALT pressed.');
        
          e.preventDefault(); //because ALT focusout the element
      }
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Press modifier key: </label>
<strong id="msg"></strong>

Solution 4 - Javascript

In most instances the ALT, CTRL,and SHIFT key booleans will work to see if those keys were pressed. For example:

var altKeyPressed = instanceOfMouseEvent.altKey

When called upon, it will return true or false. For more info, go to https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/altKey

For future reference, there is also one called metaKey (NS/firefox only) which works when the meta key is pressed.

Solution 5 - Javascript

Following my comment, this is possible solution.

To check which specific modifier key is pressed, you can use KeyboardEvent Location (see table support)

To support IE8, fortunately you could use already posted solution.

Now the workaround is to set a global object with relevant properties regarding which modifier keys are held. Other ways without using global object would be possible of course.

Here, i capture event using relevant javascript listener method (jQuery doesn't support capturing phase). We capture event to handle case where keydown/keyup events propagation would be stopped for some reason by already in-use code.

/* global variable used to check modifier keys held */
/* Note: if e.g control left key and control right key are held simultaneously */
/* only first pressed key is handled (default browser behaviour?)*/
window.modifierKeys = (function() {
  /* to handle modifier keys except AltGr which is key shortcut for controlRight + alt */
  var mKeys = {};
  /* to fire keydown event only once per key held*/
  var lastEvent, heldKeys = {};
  // capture event to avoid any event stopped propagation
  document.addEventListener('keydown', function(e) {
    if (lastEvent && lastEvent.which == e.which) {
      return;
    }
    lastEvent = e;
    heldKeys[e.which] = true;
    setModifierKey(e);
  }, true);
  // capture event to avoid any event stopped propagation
  document.addEventListener('keyup', function(e) {
    lastEvent = null;
    delete heldKeys[e.which];
    setModifierKey(e);
  }, true);

  function setModifierKey(e) {
    mKeys.alt = e.altKey;
    mKeys.ctrlLeft = e.ctrlKey && e.location === 1;
    mKeys.ctrlRight = e.ctrlKey && e.location === 2;
    mKeys.shiftLeft = e.shiftKey && e.location === 1;
    mKeys.shiftRight = e.shiftKey && e.location === 2;
  }
  return mKeys;
})();

/* on div click, check for global object */
$('.modifierKey').on('click', function() {
  console.log(modifierKeys);
  /* for demo purpose */
  $('.info').text(function() {
    var txt = [];
    for (var p in modifierKeys) {
      if (modifierKeys[p]) txt.push(p);
    }
    return txt.toString();
  });
})

/* for demo purpose */

.info:not(:empty) {
  border: 1px solid red;
  padding: .1em .5em;
  font-weight: bold;
}
.info:not(:empty):after {
  content: " held";
  font-weight: normal;
 }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="modifierKey" tabindex="-1">
  DIV to catch modifier keys on click
</div>
<br>
<span class="info"></span>

As side notes:

  • ALT GR key is a shortcut key for CTRL-Right & ALT keys
  • holding simultaneously two indentical modifier keys (e.g Shift-Left & Shift-Rigth keys), would result in only first one to be handled (seems like default browser behaviour, so anyway, seems right!)

Solution 6 - Javascript

Just thought I would add an answer appropriate for 2020.


You can now also use MouseEvent.getModifierState() for this - it's supported by most browsers as of time of writing.

document.addEventListener("click", (evn) => {
  const shift = evn.getModifierState("Shift");
  const ctrl = evn.getModifierState("Control");
  const alt = evn.getModifierState("Alt");

  console.log("Mouse pressed! Modifiers:");
  console.table({shift, ctrl, alt});
});

Example

Caveats:

  • Notably, this API does not distinguish between left and right modifiers. If you care about that, you are kind of out of luck. But I imagine this only matters for a small number of use cases.

  • One of the main benefits of this API is that it supports modifiers other than shift, ctrl, and alt. However the specific behaviour is somewhat erratic across different OSes due to innate platform differences. Check here before you use them.

Solution 7 - Javascript

Use js-hotkeys. It is a jQuery plugin.

This is a test to show what you are looking for. It also shows you how to capture left, right, up, down keys standard and those from numeric key pad (the one with numbers 2,4,6,8)! http://afro.systems.googlepages.com/test-static-08.html

Solution 8 - Javascript

Easier than anything: you use keydown event to check if it's Ctrl (17) or Shift (16), you then use keyup event to check if it's Enter (13) and Ctrl or Shift hit before (on key down) cancel Ctrl or Shift on any keyup but Enter

Solution 9 - Javascript

There are some reasons that right and left CTRL,SHIFT & ALT keys are not distinguishable because

  1. keyCodes are same
  2. Many laptop keyboards may not have two control keys Taken a Reference : https://stackoverflow.com/questions/4590883/how-can-i-tell-if-an-event-comes-from-right-ctrl-key

Solution 10 - Javascript

Works like a charm! and on Chrome, Firefox, IE, and Edge too ;) https://jsfiddle.net/55g5utsk/2/

var a=[];
function keyName(p){
	var cases = {16:'Shift',17:'CTRL',18:'Alt'};
	return cases[p] ? cases[p] : 'KeyCode: '+p;
}
function keyPosition(p){
	var cases = {1:'Left',2:'Right'};
	return cases[p] ? cases[p]+' ' : '';
}
$('input').on('keydown',function(e){
	a.push(keyPosition(e.originalEvent.location)+keyName(e.keyCode));
})
$('input').on('keyup',function(){
	var c='';
    var removeDuplicates = [];
    $.each(a, function(i, el){
		if ($.inArray(el, removeDuplicates) === -1) {
           removeDuplicates.push(el);
           c=c+(el)+' + ';
        }
    });
	a=[];
	alert(c.slice(0, -3))
});

> Following, a version with the click event http://jsfiddle.net/2pL0tzx9/

var a=[];
function keyName(p){
	var cases = {16:'Shift',17:'CTRL',18:'Alt'};
	return cases[p] ? cases[p] : '';
}
function keyPosition(p){
	var cases = {1:'Left',2:'Right'};
	return cases[p] ? cases[p]+' ' : '';
}
$(document).on('keydown',function(e){
	a.push(keyPosition(e.originalEvent.location)+keyName(e.keyCode));
})
$('#my_id').on('click',function(){
	var c='';
    var removeDuplicates = [];
    a =a.filter(function(v){return v!==''});
    $.each(a, function(i, el){
      if ($.inArray(el, removeDuplicates) === -1){
          removeDuplicates.push(el);
		  c=c+(el)+' + ';
      }
    });
    if (c) alert(c.slice(0, -3));
    a=[];	
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMisha MoroshkoView Question on Stackoverflow
Solution 1 - JavascriptJohn HartsockView Answer on Stackoverflow
Solution 2 - JavascriptjAndyView Answer on Stackoverflow
Solution 3 - JavascriptIbrahim KhanView Answer on Stackoverflow
Solution 4 - JavascriptDJHakimView Answer on Stackoverflow
Solution 5 - JavascriptA. WolffView Answer on Stackoverflow
Solution 6 - JavascriptcyqsimonView Answer on Stackoverflow
Solution 7 - Javascriptuser347594View Answer on Stackoverflow
Solution 8 - JavascriptOtvazhniiView Answer on Stackoverflow
Solution 9 - JavascriptParth PatelView Answer on Stackoverflow
Solution 10 - JavascriptVixedView Answer on Stackoverflow