118

I would like to catch a click event with jQuery and be able to tell if a key was pressed at the same time so I can fork within the callback function based on the keypress event.

For example:

$("button").click(function() {
    if([KEYPRESSED WHILE CLICKED]) {
        // Do something...
    } else {
        // Do something different...
    }
});

Is this possible at all or how can it be done if it is possible?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
daniel smith
  • 1,181
  • 2
  • 7
  • 3

5 Answers5

193

You can easily detect the shift, alt and control keys from the event properties;

$("button").click(function(evt) {
  if (evt.ctrlKey)
    alert('Ctrl down');
  if (evt.altKey)
    alert('Alt down');
  // ...
});

See quirksmode for more properties. If you want to detect other keys, see cletus's answer.

Community
  • 1
  • 1
kkyy
  • 12,214
  • 3
  • 32
  • 27
  • 3
    I don't see that property on the jQuery Event object: http://api.jquery.com/category/events/event-object/ – cletus Mar 15 '10 at 07:35
  • 1
    Well, as the page says, "Most properties from the original event are copied over and normalized to the new event object." ctrlKey, altKey etc. are part of the ecmascript standard (see the first link on the aforementioned jquery api page), so (at least in decent browsers) the event object usually has also those properties set. – kkyy Mar 15 '10 at 07:43
  • 3
    Quirks mode only says these are defined *in* a key event .. no mention about a mouse event. –  Sep 14 '12 at 23:39
  • 7
    You can even detect Mac OS X's command key using `if (e.metaKey) alert('Command down')`. Here's a nice article about key events in JS http://unixpapa.com/js/key.html – F Lekschas Nov 02 '15 at 23:39
52

You need to separately track the key status using keydown() and keyup():

var ctrlPressed = false;
$(window).keydown(function(evt) {
  if (evt.which == 17) { // ctrl
    ctrlPressed = true;
  }
}).keyup(function(evt) {
  if (evt.which == 17) { // ctrl
    ctrlPressed = false;
  }
});

See the list of key codes. Now you can check that:

$("button").click(function() {
  if (ctrlPressed) {
    // do something
  } else {
    // do something else
  }
});
cletus
  • 616,129
  • 168
  • 910
  • 942
  • 6
    One down side of this method (not that I know a better way) is if you are detecting the ALT key, and the user ALT-Tabs to another window, then the keyup event is not detected by the browser because it occurred on another application. From that point, jquery thinks the key is down, until they keyup within your jquery app. This only matters with the ALT key, as far as I can imagine. – Flat Cat Sep 25 '14 at 16:16
  • 1
    For Mac OS X that would be Cmd-Tab, but I think the principal still holds – murftown Apr 14 '16 at 16:44
  • 1
    Or Ctrl+Tab for changing browser's tab – Seeven Sep 21 '17 at 15:29
9

I was able to use it with JavaScript alone

 <a  href="" onclick="return Show(event)"></a>

  function Show(event) {
            if (event.ctrlKey) { 
                 alert('Ctrl down');
            }
     }
Arun Prasad E S
  • 9,489
  • 8
  • 74
  • 87
5

Without stealing @Arun Prasad's thunder, here is a pure JS snippet I rehashed to stop the default action, which would otherwise open a new window if CTL+click is pressed.

function Show(event) 
{
  if (event.ctrlKey) 
  {
    alert('Ctrl held down which clicked');
  } 
  else 
  {
    alert('Ctrl NOT pressed');
  }
  return false
}
<p>Hold down CTL on the link to get a different message</p>

<a href="" onclick="return Show(event)">click me</a>
vr_driver
  • 1,867
  • 28
  • 39
0

let isCtrlClicked = false;
let selectedContainer = [];
document.addEventListener("keydown", function(e) {
  if (e.key === "Control") {
    isCtrlClicked = true;
  }
});

document.addEventListener("keyup", function(e) {
  if (e.key === "Control") {
    isCtrlClicked = false;
    selectedContainer.forEach(item => {
      item.elem.style.backgroundColor = "";
      item.elem.dataset.isAlreaySelected = "0";
      delete item.elem.dataset.position;
    });
    selectedContainer = selectedContainer.filter(item => item.active);
    console.log(selectedContainer);
    selectedContainer = [];
  }
});

const main = document.getElementById("main");
for (let i = 0; i < main.childElementCount; i++) {
  main.children[i].dataset.isAlreaySelected = "0";
  main.children[i].addEventListener("click", function(e) {
    const isAlreaySelected = e.currentTarget.dataset.isAlreaySelected;
    const position = parseInt(e.currentTarget.dataset.position);
    if (isCtrlClicked && isAlreaySelected == "0") {
      e.currentTarget.style.backgroundColor = "rgba(0,0,200,0.2)";
      selectedContainer.push({
        elem: e.currentTarget,
        active: true
      });
      e.currentTarget.dataset.position = selectedContainer.length - 1;
      e.currentTarget.dataset.isAlreaySelected = "1";
    } else {
      e.currentTarget.style.backgroundColor = "";
      if (position > -1) {
        e.currentTarget.dataset.isAlreaySelected = "0";
        delete e.currentTarget.dataset.position;
        selectedContainer[position].active = false;
      }
    }
  });
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#main {
  display: flex;
}

#main>div {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: auto;
  text-align: center;
  border: 1px solid grey;
  width: 100px;
  height: 100px;
  margin: 1rem;
}
<div id="main">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>
hp-01
  • 11
  • 3