How can I say that keydown will trigger a keypress event and in this case will ignore it?

I am not very happy with key events in javascript. I need to write both letters for writing (I write text on <canvas> ) and function keys (escape) for other commands.

In Firefox, this works because Firefox fires a keypress event for any key. This is very convenient, but the specification directly allows it :

If supported by the user agent, this event MUST be dispatched when a key is pressed , if and only if this key usually generates a character value .

I do not agree with this specification as I see no reason for this. But, as now, I can not do anything about it.

The problem is that Google Chrome follows this specification and does not start keypress for function keys. However, it does not float keydown for all keys.

My program has only one key event handler. It expects an event containing keyCode (physical key identifier and optionally charCode , equivalent character value (for keys, where that makes sense).

keydown The event contains no characters in any browser ! It contains only keyCode . Therefore, if you define the Ctrl + Z combination and listen to the keydown event, your program will be violated for users who have a QWERTZ layout, because the physical location of the key ( keyCode ) is still unchanged.

If you listen to both keydown and keypress , the character events will fire twice (the beacuse character starts keydown first, and then keypress with the corresponding charCode property)

What I need?

Based on the above, I need to ignore the keydown event for keys that will keypress . By doing this, I can capture Esc in keydown and characters in keypress .

How could I do this?

Relevant Code:

  //Keypress for character codes div.addEventListener("keypress", function(event) { console.log(event); if(_this.editor.event(event)) { console.log("Event canceled."); event.preventDefault(); event.cancelBubble = true; return false; } return true; }); //Keydown for Esc and the likes div.addEventListener("keydown", function(event) { //Character events are handled by keypress if(event.charCode!=0) //Does NOT work - in keydown, charCode is ALLWAYS 0 return true; console.log(event); if(_this.editor.event(event)) { console.log("Event canceled."); event.preventDefault(); event.cancelBubble = true; return false; } return true; }); 

Interactive example

I decided that I spend a lot of time creating JSFiddles, and in fact this does not increase the chances of getting an answer, so I downloaded the actual project instead.

Click on the white square in Firefox, press T , enter text, press Esc , press Esc . After seconds Esc, the cursor should return to normal. Try drawing and press Ctrl + Z.

Repeat the process in Google Chrome. Escape does not work because keypress does not work. For some reason, the Ctrl + Z event fires an event with keyCode 26.

From chat and comments:

@someDoge created a fiddle that I expanded, and which now shows the situation well. As you can see, you can know that the character is not and ignores it when you press a key. But you cannot know that tab is not a character and cancels it in keydown (unless you have a fixed array of code values ​​in the form of @someDoge comments in the comments).

+7
javascript events keyboard-events
source share
1 answer

You need to listen for keyup events instead of keydown , this way you will not get two separate generated events.

Then you can handle 2 types of events using the same handler function, which will either receive a charCode or not, depending on whether the particular key generated the "keypress" event. As long as you prevent bubbles, your handler will only be called once.

Regarding the issue with Chrome CTRL + Z: I don’t see how you can get charCode if the control key is pressed, as it seems to only generate a keyup event.

+2
source share

All Articles