What's the theory behind jQuery keypress, keydown, keyup black magic (on Macs)? [closed]
Asked Answered
M

3

49

I am confused about the various behaviors of keypress, keydown, and keyup. It seems that I have missed an important piece of documentation, one that explains the subtleties and nuances of this trio. Could someone help me to figure out which document I need to read in order to more effectively use these events? In case you want details, see below.

@o.v.: you asked me to show some code, but it's not really a specific problem in the code that I'm trying to solve. I'm trying to get a handle on the behaviors of these event handlers and asking someone who understands them to point me to a good piece of documentation.

I use jQuery to build an input form and insert it into my document. It works just fine, mostly. I want the form to respond to the keyboard like most other input forms I see out there: the esc key should dismiss the form the same as clicking the cancel button, and because the form has a <textarea> on it, cmd + enter should be the same as clicking the OK button. It seems simple enough to use the keypress event. The problem is that Chrome doesn't call my keypress handler for the esc key or cmd + enter. It fires for ctrl + enter and option + enter and for alphanumerics, but not cmd + enter.

So I'll use keyup instead. I get keyup for esc, and keyup for cmd, and keyup for enter, great. But I don't get keyup for the enter key while I'm holding down cmd.

Third time's the charm, you might think keydown seems to work, but with keydown, you get repeat keys. I know, all you have to do is unbind the handler the first time you're called, but it just seems weird that the three different event types would behave so differently. Why is this? Is there an obvious document out there that I obviously haven't read?

Mercurialize answered 10/10, 2012 at 20:1 Comment(1)
"Not a real question"? I had the same doubt about the trio and had no idea I had an "unreal" question. Well, at least, now I have a better idea what behaviors to look for next time I want to (not) vote for a candidate.Arapaho
A
90

Keypress:


The keypress event is sent to an element when the browser registers keyboard input. This is similar to the keydown event, except in the case of key repeats. If the user presses and holds a key, a keydown event is triggered once, but separate keypress events are triggered for each inserted character. In addition, modifier keys (such as Shift) trigger keydown events but not keypress events.

Keydown:


The keydown event is sent to an element when the user first presses a key on the keyboard. It can be attached to any element, but the event is only sent to the element that has the focus. Focusable elements can vary between browsers, but form elements can always get focus so are reasonable candidates for this event type.

Keyup:


The keyup event is sent to an element when the user releases a key on the keyboard. It can be attached to any element, but the event is only sent to the element that has the focus. Focusable elements can vary between browsers, but form elements can always get focus so are reasonable candidates for this event type.

Also, this is a handy piece of information that is usually glossed over:


If key presses anywhere need to be caught (for example, to implement global shortcut keys on a page), it is useful to attach this behavior to the document object. Because of event bubbling, all key presses will make their way up the DOM to the document object unless explicitly stopped.

To determine which character was entered, examine the event object that is passed to the handler function. While browsers use differing properties to store this information, jQuery normalizes the .which property so you can reliably use it to retrieve the character code.

Note that keydown and keyup provide a code indicating which key is pressed, while keypress indicates which character was entered. For example, a lowercase "a" will be reported as 65 by keydown and keyup, but as 97 by keypress. An uppercase "A" is reported as 65 by all events. Because of this distinction, when catching special keystrokes such as arrow keys, .keydown() or .keyup() is a better choice.

More information regarding the cmd key on MACs: jQuery key code for command key

Amphictyony answered 10/10, 2012 at 20:9 Comment(1)
Also one can go over this excellent article to understand clearly unixpapa.com/js/key.htmlEnid
S
5

This article is a good resource explaining the differences between keyup, keydown and keypress.

The short answer is there is no easy way to handle them other than to account for the different browsers.

The way I personally handle it in a Bootstrap plugin I wrote is by creating a custom method to check which event is supported. Coincidentally a very similar method showed up in the official Bootstrap version a little while later :P

//------------------------------------------------------------------
//
//  Check if an event is supported by the browser eg. 'keypress'
//  * This was included to handle the "exhaustive deprecation" of jQuery.browser in jQuery 1.8
//
eventSupported: function(eventName) {         
    var isSupported = (eventName in this.$element);

    if (!isSupported) {
      this.$element.setAttribute(eventName, 'return;');
      isSupported = typeof this.$element[eventName] === 'function';
    }

    return isSupported;
}

Later on I use it in my code to attach event handlers:

if (this.eventSupported('keydown')) {
  this.$element.on('keydown', $.proxy(this.keypress, this));
}
Sable answered 10/10, 2012 at 20:9 Comment(0)
S
1

You have to remember that when validating a KeyboardEvent on a mac, modifier key will not be picked up as event.ctrlKey but rather an event.metaKey. Further documentation is available on MDN.

Without seeing any code, my bet is on this being the reason for ⌘+Enter not being picked up.

Septet answered 11/10, 2012 at 1:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.