I have a question regarding the onkeypress event on JavaScript.
Is it possible to detect just Cntl key or Alt Key? At the moment if both Cntl and m are pressed the onkeypress event can trigger a click. Is it possible to do just Cntl key by itself?
Looking forward to your comments
onkeypress just catches character keys. Use onkeydown and/or onkeyup for the other keys. See Peter-Paul Koch on key events.
From the looks of it, no, you can't just capture the Ctrl key. The hotkeys jQuery plugin which focuses exclusively on capturing keys doesn't capture the straight "Ctrl" key either, so I'm guessing it's not possible. You can catch it with the mouse events, but that's not quite the same thing.
http://jshotkeys.googlepages.com/test-static-01.html
Related
I understand that in Javascript, the 'keypress' event fires when a character gets inserted into the screen and the 'input' event fires when the input field of yours changes. I've seen many good explanations of the different types of events like here, but I was more wondering about the difference between those two events since they seem so similar. Specifically:
What, if at all, is the difference between keypress and input events? In my quick testing, it seems like keypress happens first, but is that it?
Under what circumstances would I use one over the other?
So actually those two events are not the same at all. Let me break it down for you.
keypress event triggers when any of your keyboard keys are pressed independently of the element you are focusing. If you press a key on a blank html page, the event will be triggered. This event is mostly used to trigger events like when there is a popup and you press escape, it hides it.
input event is specific to the case where you are currently typing or pressing keys while focusing an input element. With it, you can actually get the input value and do stuff with it like in a form, check if the password has symbols, a caps letter, and numbers.
This is the difference between those two events. They don't have the same use at all.
To answer your question about when you would use keyDown or keyUp versus input:
Navigation controls for games
Keys that don't change the text. For instance, using keyDown to detect 'esc' or 'F1' pressed. I commonly use keyDown detection of 'esc' to close popup windows
The javascript keypress event is deprecated:
https://developer.mozilla.org/en-US/docs/Web/API/Document/keypress_event
Some people advise to rely exclusively on the keydown event, eg.:
Keydown is the only keyboard event we need
https://www.mutuallyhuman.com/blog/2018/03/27/keydown-is-the-only-keyboard-event-we-need/
The problem is that keydown and keypress are not synonymous. Critically, they do not return the same character in many/most cases. Keydown represents which key on the keyboard was pressed, while keypress represents which character the user actually typed.
In English, the distinction is important with regard to case:
letter = String.fromCharCode(event.which);
When pressing the key "a" on the keyboard, letter would be "a" with keypress, but it is "A" with keydown.
The situation gets way more complicated with JCK languages because keypress receives correct characters for international keyboard layouts, unlike keydown which converts everything to single byte characters.
keydown and keyup events are now fired during IME composition:
https://www.fxsitecompat.com/en-CA/docs/2018/keydown-and-keyup-events-are-now-fired-during-ime-composition/
So, with keypress being deprecated, what should we use when we care about the character that the user intended to type, taking into account case, non-ASCII characters and multi-byte characters?
Related questions and references:
keyup event always return uppercase letter
=> The answer recommends the use of keypress.
String.fromCharCode not working on keydown event
=> The answer recommends the use of keypress.
String.fromCharCode on keypress and keydown are returning wrong characters
=> The answer notes that the keypress and keydown events are not interchangeable.
Replacement for deprecated `keypress` DOM event
=> The answer suggests using keydown without noting the difference it makes in terms of handling letter case, non-ascii characters and multi-byte characters.
Also, the suggested alternative beforeinput does not appear to have any browser support.
Alternative for Keypress Event in Firefox Version 65+
=> Question summarily downvoted, with a comment suggesting using keydown or beforeinput without having addressed any of the pitfalls mentioned above.
Quick background:
when a key is pressed in a browser, three events are generated: keyDown, keyPress and keyUp.
keyDown and keyUp have a keyCode property which is approximately the physical key pressed.
keyPress also has charCode property set which takes into account modifier keys and keyboard layout (A and a have same keyCode but a different charCode).
all three events have properties that indicate which modifier keys were pressed during those events.
I'm the main noVNC developer and I have a tough problem: noVNC needs the translated charCode value without using the keyPress event for the following reasons:
noVNC needs to send the keyDown and keyUp events separately to the VNC server (otherwise it's not a completely functional VNC client).
more importantly, noVNC needs to prevent the default keyboard actions while connected which means calling the preventDefault() method of the keyDown event. This has the side-effect of also preventing the keyPress event from firing.
Due to differences in keyboard layouts (i.e. different keyCode to charCode mappings) I've determine that noVNC will need a lookup table for different keyboard layouts.
But here is the real problem: on alternate layouts, some different physical keys have the SAME keyCode. For example, with an azerty (French) keyboard layout the '-' (dash) and '_' underscore keys both generate keyCode 189. Ack!!!
So ... how do I get proper keyCode to charCode mapping and prevent default browser actions at the same time?
BTW, I suspect the solution to this will be applicable to other interactive web applications and HTML5 games since you often want to be able to know full information about the key pressed without triggering any additional browser response to that keypress.
Useful links:
Here is an useful test page that show the three events and some other useful properties.
Summary of the crazy state of key events in Javascript (thanks #Tim)
Quirksmode Detecting keystrokes
Quirksmode Events - key events
noVNC issue with more discussion of the problem.
Solution: see my post below.
I have solved my own question. It's not a 100% solution but it should cover most of what is needed. Hopefully there will be a cleaner solution when browser vendors start integrating DOM Level 3 Events.
Just to re-iterate the main constraints:
The key down and key up events should be reported/sent at the time they actually happen. I.e. sending a key down and key up together during the keyPress event is insufficient.
Many key combinations must be fully handled during the keyDown event either because they never trigger a keyPress event (i.e. Ctrl key) or because the default action must be stopped in keyDown (WebKit) and doing so prevents the keyPress event from happening.
The key down and key events should report the translated character code and not keyCode value.
Without some out-of-the-box epiphany, the current browser implementations appear to prevent all three constraints from being fulfilled completely. So I have decided to relax constraint #3 just a bit.
On browser keyDown event add the event to a key down list and check to see if it is a safe (no undesirable browser default behavior) key combination:
Safe: do nothing until the keyPress.
Unsafe: report/send a key down event immediately. This is where constraint #3 is relaxed because these limited key combinations are not translated to a character code (many of them don't have them though anyways).
On browser keyPress event (which happens immediately after the keyDown event) check to see if it is a safe key combination:
Safe: report/send a key down event. Update the key down list using the translated character code (event.which).
Unsafe: do nothing since it was already reported/sent during keyDown.
On browser keyUp event, find and remove the matching event from the key down list and use the translated code to report/send the key up event.
Some additional links for those interesting:
The noVNC commit with the change.
Some wiki notes on the issues as related to noVNC.
This solution has been adopted in RedHat's Broadway project (HTML5 GTK+ backend).
This is an absolute minefield and I would urge you not to attempt this if you can possibly avoid it. Not only is there a long and tangled history of browser manufacturers not agreeing on key event behaviour, there is also the fact that they still don't agree and are still regularly changing the key behaviour of their browsers.
The following is the best I can offer and the definitive resource on browser key events: http://unixpapa.com/js/key.html
If you have to do this, I think you're going to end up with loads of key code mapping tables that will go out of date very quickly. Good luck.
Why isn't backspace being detected using jQuery keypress event?
$("#field").keypress(function(event){alert(event.which);});
Try using keydownand keyupfunctions instead for IE.
Javascript e.keyCode doesn't catch Backspace/Del in IE
The "keypress" event is (in its original IE form, and in Safari/Chrome) about an actual character being added to a text field. The backspace key clearly does not add a new character to the field value, so it causes no keypress event.
Firefox and Opera are a little more willy-nilly about generating typing events.
PPK (quirksmode) considers the IE and Webkit behaviors to be the sensible ones, and I pretty much agree.
The onKeyUp alone will do all the keyboard key detection in chrome..
I'm not asking this because I need a work-a-around. I have one that works fine, but I want to know WHY it doesn't. Is this bug in Javascript (or JQuery because I was using the JQuery .keypress handler) or is there a specific reason why this is so?
The keypress event is designed for handling a character typed by the user rather than detecting keyboard activity and the delete and backspace keys do not generate characters. Some browsers blur this line somewhat but the general principle is that the keyup and keydown events are there to detect any key being pressed and telling you about which key it is while keypress is for detecting an actual character being typed.
The short answer is that the onkeypress event is not fired for all key types in all browsers. Check the manual for your browser.
Why?
Probably not a comprehensive answer, but consider Shift, when it goes down and when it comes up relative to other keys is significant. And different keyboard hardware has different key rollover characteristics which you might want to know about in detail.