Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do international keyboards work with JavaScript keyboard events?

I've written a text editor in JavaScript that draws directly to a Canvas element (for various reasons, but my primary reason is so I can slap that canvas onto a WebGL mesh as a texture). As a happy surprise, it's been easier to implement that any content-editable solutions I've found.

One thing I noticed early on were complaints from people with keyboard layouts other than en-US QWERTY that some keys were showing an incorrect letter. After some fiddling around with Windows' language settings and on-screen keyboard, I created a code-page based solution that maps keyCodes to character-strings for different locales directly, rather than just assuming "keyCode 51 with no modifier keys is the number 3". Because it's not, on some keyboards it's double-qoute.

But there are still some oddities. A few examples (note that all of these examples are based on using the Windows on-screen keyboard, so I'm only assuming this correlates with reality):

  • The French AZERTY keyboard sends a keyDown and keyPressed events when a letter U is typed, but never a keyUp. I'm assuming U must be need to be combined with another key, but not knowing what the correct behavior should be is preventing me from writing the right code. EDIT: I still haven't quite figured out what this means, other than--perhaps--that key is only used in one word the entire French language?
  • The German QWERTZ keyboard has a ^ (it's not a caret, it looks larger) key where the ` (backtick) key would be on the US keyboard, and a backtick key where the = (equals) key would be on the US keyboard. In both cases, they send keyDown and keyUp events, but do not appear to print anything in any text editor I use, until they are hit a second time, and then two characters are printed. Is this something to do with combining marks? I can't find anything about it. EDIT: These are called dead keys, and they create accented letters. A lot of keyboard layouts have them. I'll create a key-sequencing system for this that will also help provide support for more complex, Emacs-style keyboard shortcuts, if any are chosen.
  • The UK QWERTY keyboard has a backslash that requires use of an ALT-GRAPH key (Right-Alt key on US keyboards). There is a location property of KeyboardEvent that could be used to determine which of the ALT keys are pressed, but it apparently isn't available in Safari. This is pretty low priority, as Safari typically only accounts for 1% or less of my traffic. However, is there a property that works for Safari that I can use as a fallback? EDIT: I'll handle this as the rest of my code-page system works for the differences between lower- and upper-case keys. It's just a different code page for a new modifier key. I'll have to change how the modifier keys are detected, but it's a minor change and will actually fit into the keyboard shortcut system quite easily.
  • Finally, judging from the Windows' language settings, there are a lot of different keyboard layouts in the world. Is there any listing of the keycodes and behaviors anywhere? I'd rather not have to manually test every keyboard just to generate a new code-page for them.

The first two problems are the biggest. I can figure out a solution to these if I just know what the behavior is supposed to be. The third issue will fit into my code-page system, though I'll have to change how I read modifier keys. The final issue, I could probably pay someone to cover.

And I'm fine with not being able to solve it for all users in all browsers 100% of the time. But most of the information I've ran across is basically "don't bother", which really only sounds more like "I don't know".

EDIT: selecting the layout isn't a concern. I provide it as an option to the user, if things aren't working for them. I think that's about the best thing one can do in this situation, but obviously I would auto-detect if I could. I'm really only concerned with getting the right behavior given that the right layout has already been chosen.

I would like to avoid anything involving the keyPress event, given that it isn't perfectly reliable. If I had a reliable source of data on keyboard layouts, it wouldn't be an issue.

like image 764
moron4hire Avatar asked Jan 09 '15 12:01

moron4hire


People also ask

How do I use keyboard events in JavaScript?

There are three different keyboard events in JavaScript: keydown : Keydown happens when the key is pressed down, and auto repeats if the key is pressed down for long. keypress : This event is fired when an alphabetic, numeric, or punctuation key is pressed down. keyup : Keyup happens when the key is released.

What is international keyboard?

The US-International keyboard uses the ', `, ~, ^, " as dead keys (highlighted in blue below), and uses Right-ALT plus !, ?, and a number of other keys to produce characters not normally available.


1 Answers

You can't get keyboard layout...

There's no way (with a pure JS solution) to detect the user's keyboard layout.

Note the "en-US" or "en-GB" doesn't map to any specific / agreed keyboard layout for those languages. The user's language is independent to how their keys map to a character.

You can make assumptions based on their locale / language code, but this doesn't offer any guarantee - it just increases the probability that you're catering for the appropriate layout.

Also see these questions:

Translate Javascript keyCode into charCode for non-U.S. keyboard layout (i.e. azerty)

Detect keyboard layout with javascript

...but you can get the character entered with it:

However, depending on your required browser support (which using canvas, should be quite good), you could try to use the charCode property:

http://www.w3schools.com/jsref/event_key_charcode.asp

var unicodeCharCode = e.charCode;

Note that this will not return the actual character - you'll get the number representing it (NOT the key):

The Unicode character code is the number of a character (e.g. the number "97" represents the letter "a").

You can easily map these codes to characters as required or just use the built in function:

var userInput = String.fromCharCode(unicodeCharCode);
  • Being clever / making work for yourself, you could also (fairly trivially) write a library to guess the keyboard layout from the charCode's returned for certain keyCode's. Don't though :)

Alternative approach:

One suggestion to use as a workaround would be to use a hidden (or at least discrete) text input / text box, which your app sets focus on.

When your app detects a keypress / keydown etc. you can grab the value the user has entered and render it on your canvas.

As you're already capturing the keyboard events, handling combinations should be easy (if necessary). In some ways even that wouldn't be required as you only have to monitor the input length of the user input (your app doesn't have to care if the user needed a three-key combination to enter the character, you just grab the result).

like image 123
Michael Avatar answered Sep 19 '22 02:09

Michael