99

I have an anchor tag that calls a JavaScript function.

With or without JQuery how do I determine if the shift key is down while the link is clicked?

The following code does NOT work because keypress is only fired if a "real key" (not the shift key) is pressed. (I was hoping it would fire if just the shift key alone was pressed.)

var shifted = false;

$(function() {                           
    $(document).keypress(function(e) {
        shifted = e.shiftKey;
        alert('shiftkey='+e.shiftkey);
    });

    $(document).keyup(function(e) {
        shifted = false;
    });
}

...

function myfunction() {
  //shift is always false b/c keypress not fired above
}
Pete Alvin
  • 4,646
  • 9
  • 39
  • 56
  • 4
    the following code also does not work because you typed `shiftkey` instead of `shiftKey` :-) – Simon_Weaver Apr 25 '14 at 22:37
  • If you need to know that to avoid calling the handler when pressing `shift+click`, use [`filter-altered-clicks`](https://github.com/bfred-it/filter-altered-clicks) – fregante Oct 10 '16 at 16:48

12 Answers12

111
    $(document).on('keyup keydown', function(e){shifted = e.shiftKey} );
martynas
  • 12,120
  • 3
  • 55
  • 60
hluk
  • 5,848
  • 2
  • 21
  • 19
  • 22
    This worked for me but interrupted all standard shortcuts that didn't involve `shift` since the function returns `false`. I needed to explicitly `return true` to allow crtl+r, ctrl+s, ctrl+p etc. – John H Feb 26 '13 at 00:16
  • 4
    So the suggestion is to use keydown instead of keypress. – rwitzel Mar 31 '15 at 18:56
  • Strange, I get only keydown events, no keyup. – Gerry Sep 20 '19 at 17:37
  • @rwitzel keydown and keyup allow you to track the actual state of the shift key as they are fired for every key on the keyboard. Keypress is not always fired e.g. not fired when only the shift key is pressed. – jakubiszon Oct 25 '19 at 19:38
  • @Gerry it could be there is some other event handler on your page which breaks the event chain. Check on a blank/new page first (one which doesn't include all your scripts) - it will work just right. – jakubiszon Oct 25 '19 at 19:43
  • $(document).keyup(function (e) { } and $(document).keydown(function (e) { } is what worked for me – Gerry Oct 28 '19 at 16:09
  • This is best solution: https://stackoverflow.com/a/1165307/4058449 – Jelle Blaauw Jul 07 '20 at 15:08
81

Here is the key code for each key stroke in JavaScript. You can use that and detect if the user has pressed the Shift key.

backspace           8
tab                 9
enter               13
shift               16
ctrl                17
alt                 18
pause/break         19
caps lock           20
escape              27
page up             33
page down           34
end                 35
home                36
left arrow          37
up arrow            38
right arrow         39
down arrow          40
insert              45
delete              46
0                   48
1                   49
2                   50
3                   51
4                   52
5                   53
6                   54
7                   55
8                   56
9                   57
a                   65
b                   66
c                   67
d                   68
e                   69
f                   70
g                   71
h                   72
i                   73
j                   74
k                   75
l                   76
m                   77
n                   78
o                   79
p                   80
q                   81
r                   82
s                   83
t                   84
u                   85
v                   86
w                   87
x                   88
y                   89
z                   90
left window key     91
right window key    92
select key          93
numpad 0            96
numpad 1            97
numpad 2            98
numpad 3            99
numpad 4            100
numpad 5            101
numpad 6            102
numpad 7            103
numpad 8            104
numpad 9            105
multiply            106
add                 107
subtract            109
decimal point       110
divide              111
f1                  112
f2                  113
f3                  114
f4                  115
f5                  116
f6                  117
f7                  118
f8                  119
f9                  120
f10                 121
f11                 122
f12                 123
num lock            144
scroll lock         145
semi-colon          186
equal sign          187
comma               188
dash                189
period              190
forward slash       191
grave accent        192
open bracket        219
back slash          220
close braket        221
single quote        222

Not all browsers handle the keypress event well, so use either the key up or the key down event, like this:

$(document).keydown(function (e) {
    if (e.keyCode == 16) {
        alert(e.which + " or Shift was pressed");
    }
});
Pang
  • 9,564
  • 146
  • 81
  • 122
Jsinh
  • 2,539
  • 1
  • 19
  • 35
  • 2
    Use `event.key` instead! It will give you the char directly, ex: "a", "1", "LeftArrow" – Gibolt Sep 05 '17 at 21:09
  • Even better in its VanillaJS version: ```document.addEventListener("keydown", function(e){ console.log(e.which); });``` – Evgeny Aug 26 '18 at 14:57
30

For mouse events, I know that in Firefox at least the "shiftKey" property on the event object will tell you if the shift key is down. It's documented at MSDN but I haven't tried it in forever so I don't recall if IE does this right.

Thus you should be able to check for "shiftKey" on the event object in your "click" handler.

Pointy
  • 405,095
  • 59
  • 585
  • 614
23

I had a similar problem, trying to capture a 'shift+click' but since I was using a third party control with a callback rather than the standard click handler, I didn't have access to the event object and its associated e.shiftKey.

I ended up handling the mouse down event to record the shift-ness and then using it later in my callback.

    var shiftHeld = false;
    $('#control').on('mousedown', function (e) { shiftHeld = e.shiftKey });

Posted just in case someone else ends up here searching for a solution to this problem.

tonycoupland
  • 4,127
  • 1
  • 28
  • 27
10

For checking if the shiftkey is pressed while clicking with the mouse, there is an exact property in the click event object: shiftKey (and also for ctrl and alt and meta key): https://www.w3schools.com/jsref/event_shiftkey.asp

So using jQuery:

$('#anchor').on('click', function (e) {
    if (e.shiftKey) {
        // your code
    }
});
bugovicsb
  • 422
  • 1
  • 7
  • 15
7

I have used a method to test if any specific key is pressed by storing the currently pressed key codes in an array:

var keysPressed = [],
    shiftCode = 16;

$(document).on("keyup keydown", function(e) {
    switch(e.type) {
        case "keydown" :
            keysPressed.push(e.keyCode);
            break;
        case "keyup" :
            var idx = keysPressed.indexOf(e.keyCode);
            if (idx >= 0)
                keysPressed.splice(idx, 1);
            break;
    }
});

$("a.shifty").on("click", function(e) {
    e.preventDefault();
    console.log("Shift Pressed: " + (isKeyPressed(shiftCode) ? "true" : "false"));
});

function isKeyPressed(code) {
    return keysPressed.indexOf(code) >= 0;
}

Here is the jsfiddle

Corey
  • 5,818
  • 2
  • 24
  • 37
  • 4
    Cool solution but it needs a minor fix on keyup: while (idx >= 0){ keysPressed.splice(idx, 1); idx = avpg.keysPressed.indexOf(e.keyCode); } Otherwise, only the first occurence of a keypress is removed. To notice this, hold down shift for a few seconds. The array fills up with shift codes, but only one of them is removed on keyup. – pkExec Nov 26 '15 at 13:51
  • Or patch: case "keydown": { if (!this.keysPressed.includes(e.keyCode)) { this.keysPressed.push(e.keyCode); } break; } – Matěj Štágl Feb 20 '22 at 10:56
7

The keypress event isn't triggered by all browsers when you click shift or ctrl, but fortunately the keydown event is.

If you switch out the keypress with keydown you might have better luck.

Chris Van Opstal
  • 36,423
  • 9
  • 73
  • 90
  • 1
    Well but the problem is he won't know for *sure* whether the shift key is pressed. Oh but I guess if the flag is set for "keyUp" too, then it'd be possible to detect when "click" is bracketed by the key events. – Pointy Sep 23 '10 at 18:07
4

The excellent JavaScript library KeyboardJS handles all types of key presses including the SHIFT key. It even allows specifying key combinations such as first pressing CTRL+x and then a.

KeyboardJS.on('shift', function() { ...handleDown... }, function() { ...handleUp... });

If you want a simple version, head to the answer by @tonycoupland):

var shiftHeld = false;
$('#control').on('mousedown', function (e) { shiftHeld = e.shiftKey });
Community
  • 1
  • 1
koppor
  • 19,079
  • 15
  • 119
  • 161
3

This works great for me:

function listenForShiftKey(e){
    var evt = e || window.event;
    if (evt.shiftKey) {
      shiftKeyDown = true;
    } else {
      shiftKeyDown = false;
    }
}
kaleazy
  • 5,922
  • 2
  • 47
  • 51
2

A more modular approach plus the ability to keep your this scope in the listeners:

var checkShift = function(fn, self) {
  return function(event) {
    if (event.shiftKey) {
      fn.call(self, event);
    }
    return true;
  };
};

$(document).on('keydown', checkShift(this.enterMode, this));
Rob Fox
  • 5,355
  • 7
  • 37
  • 63
1

If anyone's looking to detect a given key and needs to know the status of the "modifiers" (as they are called in Java), i.e. Shift, Alt and Control keys, you can do something like this, which responds to keydown on key F9, but only if none of the Shift, Alt or Control keys is currently pressed.

jqMyDiv.on( 'keydown', function( e ){
    if( ! e.shiftKey && ! e.altKey && ! e.ctrlKey ){
        console.log( e );
        if( e.originalEvent.code === 'F9' ){
          // do something 
        }
    }
});
mike rodent
  • 14,126
  • 11
  • 103
  • 157
0
var shiftDown = false;
this.onkeydown = function(evt){
    var evt2 = evt || window.event;
    var keyCode = evt2.keyCode || evt2.which;       
    if(keyCode==16)shiftDown = true;
}
this.onkeyup = function(){
    shiftDown = false;
}

demo