587

I have two functions. When enter is pressed the functions runs correctly but when escape is pressed it doesn't. What's the correct number for the escape key?

$(document).keypress(function(e) { 
    if (e.which == 13) $('.save').click();   // enter (works as expected)
    if (e.which == 27) $('.cancel').click(); // esc   (does not work)
});
Seth
  • 10,198
  • 10
  • 45
  • 68
Shishant
  • 9,256
  • 15
  • 58
  • 79
  • Keypress will return a character connected to a key ( in correct caps etc ), Keyup will return the number of hardware button pressed. For ESC you'd want the hardware code 27 ( not the ascii character 27 ) – Joeri Sep 30 '15 at 19:40
  • Possible duplicate of [How to detect escape key press with JavaScript or jQuery?](http://stackoverflow.com/questions/3369593/how-to-detect-escape-key-press-with-javascript-or-jquery) – kartik Nov 22 '16 at 06:09
  • 1
    There is a really simple trick to find out whichever keyCode you want. Just open a new tab, put `document.addEventListener("keydown", e => console.log(e.keyCode))` into your browser console, click into the window and press the key you are looking for. – Wu Wei Nov 20 '19 at 14:31

16 Answers16

973

Try with the keyup event:

$(document).on('keyup', function(e) {
  if (e.key == "Enter") $('.save').click();
  if (e.key == "Escape") $('.cancel').click();
});
EricSchaefer
  • 25,272
  • 21
  • 67
  • 103
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 39
    This has nothing to do with keyup vs. keypress. To capture ESCAPE, you need to look at e.keyCode as opposed to e.which (which this example happens to do). – dkamins May 12 '10 at 03:31
  • 219
    "This has nothing to do with keyup vs. keypress" - that's incorrect, dkamins. keypress doesn't seem to be handled consistently between browsers (try out the demo at http://api.jquery.com/keypress/ in IE vs Chrome vs Firefox -- sometimes it doesn't register, and both 'which' and 'keyCode' vary) whereas keyup is consistent. e.which is the jquery-normalized value, so 'which' or 'keyCode' should both work in keyup. – Jordan Brough May 13 '10 at 03:04
  • 14
    @Jordan Brough - I would like to request you to post your comment as answer so that people read it and understand the actual meaning of your comment! since your comment is as important as the answer explaining – Murtaza Feb 03 '12 at 09:06
  • 15
    `keydown`will mimic native behaviour - at least on Windows where pressing ESC or Return in a dialog will trigger the action before the key is released. – thomthom Oct 31 '12 at 13:29
  • Any idea why i have to use window instead of document? Otherwise the event cant be catched. – YeppThat'sMe Feb 12 '13 at 18:23
  • 1
    @JordanBrough You are leaking upvotes. Pls add your comment as an answer as suggested earlier b/c ppl (comme moi-même) would like to upvote. (Leave orig comment in place as directional beacon) – cssyphus Jan 10 '15 at 00:21
  • 2
    @gibberish I've added my comment as an answer here: http://stackoverflow.com/a/28502629/58876 – Jordan Brough Feb 13 '15 at 15:14
  • 1
    I typed in keycode the entire time and wondered why it wasn't working, capital C...... – Rockstar5645 Aug 11 '15 at 17:05
  • FWIW, you can add multiple events into a single handler, so depending on the action that needs to happen, you could theoretically combine 2 of the events (.on("keyup keypress", function(){ // blah blah });, etc). I had to do this to ensure consistent behavior between browsers, and because I wasn't doing anything too intensive or anything that wrote to file/db, I was willing to take the potential hit of double-eventing in the interest of just...getting it...done. --EDITED to add that @CMS's idea is what ultimately saved me, and I tweaked it to use both keyup and keypress. --ik – ingernet Jan 17 '16 at 22:56
  • 1
    The keypess event is not meant to fire on escape! It is only meant to fire when the key produces a character. So browsers not firing keypress on escape are doing it correct https://developer.mozilla.org/en-US/docs/Web/Events/keypress – ohcibi Mar 22 '16 at 09:24
  • I have noticed that keyup works better with escape, but to get enter key you have to use keypress ( so i wont upload form id there's any) – tomekK Jun 11 '16 at 08:51
  • This is now deprecated. See the answer by @aug instead: https://stackoverflow.com/a/46064532/4033913 – Jonathan Arbely Apr 16 '21 at 00:41
84

Rather than hardcode the keycode values in your function, consider using named constants to better convey your meaning:

var KEYCODE_ENTER = 13;
var KEYCODE_ESC = 27;

$(document).keyup(function(e) {
  if (e.keyCode == KEYCODE_ENTER) $('.save').click();
  if (e.keyCode == KEYCODE_ESC) $('.cancel').click();
});

Some browsers (like FireFox, unsure of others) define a global KeyEvent object that exposes these types of constants for you. This SO question shows a nice way of defining that object in other browsers as well.

Community
  • 1
  • 1
Seth Petry-Johnson
  • 11,845
  • 7
  • 49
  • 69
  • 16
    What, 27 doesn't just jump out at you as being the escape key?!? Honestly, this really needs to be done by more people. I call them "magic numbers" and "magic strings." What does 72 mean? Why do you have a very specific and volatile string copy-pasted 300 times in your code base? etc. – vbullinger Aug 13 '12 at 20:26
  • 1
    Or you could just add a comment above each, as you're likely only using them each once. IMO just as readable – Ivan Durst Mar 01 '14 at 01:50
  • 8
    @IvanDurst you may only be using them once _per method_, but I use them multiple times in my project(s). Are you really suggesting that you'd want to (1) look up the values and (2) comment them every time you want to use a key code? I don't know about you, but I have neither the desire to memorize them nor the faith that other programmers will comment them consistently. It's about making coding easier and more consistent, not just more readable. – Seth Petry-Johnson Mar 02 '14 at 13:49
  • 2
    Someone who knows what they mean doesn't have to lookup the meaning to comment them, and typing a comment is just as quick as typing a long name. – NetMage Jul 09 '14 at 18:13
  • 2
    Not that I'm in any way against named constants, but I think it's worth noting that ENTER can be considered the exceptional case. It doesn't strike me as bad form if someone chooses to use 13 "raw" and commentless since it's a reasonable expectation that all web developers will read it as "enter" without confusion. – Semicolon Aug 09 '14 at 00:06
  • I don't think ENTER is exceptional, it may be that you have reason to use that one more than me. I wouldn't have read 13 as 'enter', and I wouldn't expect the person after me to know either. I think that developers might be familiar with related numbering systems that might be easily mixed up, e.g. for URL encoding, such as %20 for space, but 20 is the keycode for Caps lock. Better to comment it. – Liam Feb 03 '15 at 11:39
  • 7
    Whatever happened to the good old days when we used to code character constants in hex? Everyone know ESC is `0x1B` and Enter is `0x0D`, right? – David R Tribble Apr 13 '15 at 15:07
  • If you using jQuery UIyou can use the predefined constants: Such as $.ui.keyCode.BACKSPACE see https://api.jqueryui.com/jQuery.ui.keyCode/ – Sam Plus Plus Apr 24 '15 at 17:39
  • Even if the codes are not known to the next coder: You check for two different keys, one saves, one cancels. Which could they be? If they key is not obvious through the function it triggers, you have a usability issue, not a coding one. :-) Besides, JS doesn't know constants, you're wasting (a tiny bit of) resources on a variable there.I would avoid that if it's not absolutely necessary. – Mantriur May 23 '15 at 15:24
  • KEYCODE_ESC explains it's the hardware CODE 27 your looking for, while KEYCHAR_ESC would explain it's ascii/utf-8 CHARacter 27 needed. But yes most of the time these are the same number, and what's the use since JS does not throw an error when keypress == KEYCODE_ESC is checked anyway... – Joeri Sep 30 '15 at 19:45
  • 2
    you should have just left this as a comment on the accepted answer. this is just semantics and fluff on an actual answer. – Timmerz Jan 15 '17 at 08:09
  • How are these called "constants", while you declare them as variables? It would make a bit more sense if they were actually constants. But variables may be changed, point to incorrect scope, undefined etc. Introduce new possibilities for bugs, just for the sake of notation? My reasoning skills tell me it's a bad idea. My vote goes to using comments for explanation. – Slava Jan 26 '17 at 15:09
51

(Answer extracted from my previous comment)

You need to use keyup rather than keypress. e.g.:

$(document).keyup(function(e) {
  if (e.which == 13) $('.save').click();     // enter
  if (e.which == 27) $('.cancel').click();   // esc
});

keypress doesn't seem to be handled consistently between browsers (try out the demo at http://api.jquery.com/keypress in IE vs Chrome vs Firefox. Sometimes keypress doesn't register, and the values for both 'which' and 'keyCode' vary) whereas keyup is consistent.

Since there was some discussion of e.which vs e.keyCode: Note that e.which is the jquery-normalized value and is the one recommended for use:

The event.which property normalizes event.keyCode and event.charCode. It is recommended to watch event.which for keyboard key input.

(from http://api.jquery.com/event.which/)

Community
  • 1
  • 1
Jordan Brough
  • 6,808
  • 3
  • 31
  • 31
  • 6
    I'd also like to add here that browsers which don't fire `keypress` on escape are doing it right. `keypress` is meant to fire only when the key produces a character whereas `keyup` fires always. https://developer.mozilla.org/en-US/docs/Web/Events/keypress – ohcibi Mar 22 '16 at 09:26
27

To find the keycode for any key, use this simple function:

document.onkeydown = function(evt) {
    console.log(evt.keyCode);
}
Ryan Allred
  • 389
  • 3
  • 13
Hanzel
  • 453
  • 4
  • 6
18

27 is the code for the escape key. :)

Afshin Mehrabani
  • 33,262
  • 29
  • 136
  • 201
Salty
  • 6,688
  • 3
  • 33
  • 31
  • 1
    I have two functions when enter is press the functions runs correctly but not with escape key.. $(document).keypress(function(e) { if (e.which == 13) { $('.save').click(); } if (e.which == 27) { $('.cancel').click(); } }); – Shishant Jul 21 '09 at 15:43
  • $(document).keypress(function(e) { y=e.keyCode?e.keyCode:e.which;}); When I alert(y), it alerts 27 in IE and FF. Are you sure there's not something else wrong with your code? – Salty Jul 21 '09 at 15:51
15

Your best bet is

$(document).keyup(function(e) { 
    if (e.which === 13) $('.save').click();   // enter 
    if (e.which === 27) $('.cancel').click(); // esc   

    /* OPTIONAL: Only if you want other elements to ignore event */
    e.preventDefault();
    e.stopPropagation();
});

Summary

  • which is more preferable than keyCode because it is normalized
  • keyup is more preferable than keydown because keydown may occur multiple times if user keeps it pressed.
  • Do not use keypress unless you want to capture actual characters.

Interestingly Bootstrap uses keydown and keyCode in its dropdown component (as of 3.0.2)! I think it's probably poor choice there.

Related snippet from JQuery doc

While browsers use differing properties to store this information, jQuery normalizes the .which property so you can reliably use it to retrieve the key code. This code corresponds to a key on the keyboard, including codes for special keys such as arrows. For catching actual text entry, .keypress() may be a better choice.

Other item of interest: JavaScript Keypress Library

Seth
  • 10,198
  • 10
  • 45
  • 68
Shital Shah
  • 63,284
  • 17
  • 238
  • 185
9

Just posting an updated answer than e.keyCode is considered DEPRECATED on MDN.

Rather you should opt for e.key instead which supports clean names for everything. Here is the relevant copy pasta

window.addEventListener("keydown", function (event) {
  if (event.defaultPrevented) {
    return; // Do nothing if the event was already processed
  }

  switch (event.key) {
    case "ArrowDown":
      // Do something for "down arrow" key press.
      break;
    case "ArrowUp":
      // Do something for "up arrow" key press.
      break;
    case "ArrowLeft":
      // Do something for "left arrow" key press.
      break;
    case "ArrowRight":
      // Do something for "right arrow" key press.
      break;
    case "Enter":
      // Do something for "enter" or "return" key press.
      break;
    case "Escape":
      // Do something for "esc" key press.
      break;
    default:
      return; // Quit when this doesn't handle the key event.
  }

  // Cancel the default action to avoid it being handled twice
  event.preventDefault();
}, true);
aug
  • 11,138
  • 9
  • 72
  • 93
9

Try the jEscape plugin (download from google drive)

$(document).escape(function() { 
   alert('ESC button pressed'); 
});

or get keycode for cross browser

var code = (e.keyCode ? e.keyCode : e.which);
if (code === 27) alert('ESC');
if (code === 13) alert('ENTER');

maybe you can use switch

var code = (e.keyCode ? e.keyCode : e.which);
switch (code) {
    case 27:
       alert('ESC');
       break;
     case 13:
       alert('ENTER');
       break;
}
Seth
  • 10,198
  • 10
  • 45
  • 68
S. Ferit Arslan
  • 199
  • 3
  • 8
8

To explain where other answers haven't; the problem is your use of keypress.

Perhaps the event is just mis-named but keypress is defined to fire when when an actualcharacteris being inserted. I.e. text.
Whereas what you want is keydown/keyup, which fires whenever (before or after, respectively) the user depresses akey. I.e. those things on the keyboard.

The difference appears here because esc is a control character (literally 'non-printing character') and so doesn't write any text, thus not even firing keypress.
enter is weird, because even though you are using it as a control character (i.e. to control the UI), it is still inserting a new-line character, which will fire keypress.

Source: quirksmode

Hashbrown
  • 12,091
  • 8
  • 72
  • 95
8

Your code works just fine. It's most likely the window thats not focused. I use a similar function to close iframe boxes etc.

$(document).ready(function(){

    // Set focus
    setTimeout('window.focus()',1000);

});

$(document).keypress(function(e) {

    // Enable esc
    if (e.keyCode == 27) {
      parent.document.getElementById('iframediv').style.display='none';
      parent.document.getElementById('iframe').src='/views/view.empty.black.html';
    }

});
Eric Herlitz
  • 25,354
  • 27
  • 113
  • 157
8

I'm was trying to do the same thing and it was bugging the crap out of me. In firefox, it appears that if you try to do some things when the escape key is pressed, it continues processing the escape key which then cancels whatever you were trying to do. Alert works fine. But in my case, I wanted to go back in the history which did not work. Finally figured out that I had to force the propagation of the event to stop as shown below...

if (keyCode == 27)
{
    history.back();

    if (window.event)
    {
        // IE works fine anyways so this isn't really needed
        e.cancelBubble = true;
        e.returnValue = false;
    }
    else if (e.stopPropagation)
    {
        // In firefox, this is what keeps the escape key from canceling the history.back()
        e.stopPropagation();
        e.preventDefault();
    }

    return (false);
}
Billy Buerger
  • 81
  • 1
  • 1
7

To get the hex code for all the characters: http://asciitable.com/

Julien
  • 5,729
  • 4
  • 37
  • 60
  • 2
    I was gonna say..... I hate that this site is at the top of the search results because it's so damn ugly, but it does convey the necessary information. – mpen Jul 21 '09 at 17:29
  • 1
    Note that depending on event and browser, key codes do not always match ascii tables. – Alan H. Jan 31 '11 at 23:46
  • 2
    downvote: doesn't answer the question, doesn't even address the question, hex has nothing to do with the question and OP already demonstrated knowledge of esc == 27. – Jeremy May 31 '12 at 06:12
6

A robust Javascript library for capturing keyboard input and key combinations entered. It has no dependencies.

http://jaywcjlove.github.io/hotkeys/

hotkeys('enter,esc', function(event,handler){
    switch(handler.key){
        case "enter":$('.save').click();break;
        case "esc":$('.cancel').click();break;
    }
});

hotkeys understands the following modifiers: ,shiftoptionaltctrlcontrolcommand, and .

The following special keys can be used for shortcuts:backspacetab,clear,enter,return,esc,escape,space,up,down,left,right,home,end,pageup,pagedown,del,delete andf1 throughf19.

小弟调调
  • 1,315
  • 1
  • 17
  • 33
5

I know this question is asking about jquery, but for those people using jqueryui, there are constants for many of the keycodes:

$.ui.keyCode.ESCAPE

http://api.jqueryui.com/jQuery.ui.keyCode/

Troy Grosfield
  • 2,133
  • 20
  • 19
5

I have always used keyup and e.which to catch escape key.

Dalius I
  • 943
  • 11
  • 6
1
$(document).on('keydown', function(event) {
   if (event.key == "Escape") {
       alert('Esc key pressed.');
   }
});
Bruno Monteiro
  • 4,153
  • 5
  • 29
  • 48