Search code examples
mootoolskeydownkeyupnumeric-keypad

Mootools: numpad keyup and keydown events returns different key values on the same key


Can anyone shed some light on why numpad keyup and keydown events return different key values?

Consider this:

<input type="text" />
<script>
    document.getElement('input').addEvents({
    'keydown':function(e){
            console.log('keydown: code:' + e.code + ', key:' + e.key);
    },
    'keyup':function(e){
            console.log('keyup  : code:' + e.code + ', key:' + e.key + '\n');
        }
    });
</script>

I was expecting each event to return the same key value for both keydown and keyup but instead, I got the output below (after pressing 0,1,2,8 and 9):

keydown: code:96, key:0
keyup : code:96, key:`

keydown: code:97, key:1
keyup : code:97, key:a

keydown: code:98, key:2
keyup : code:98, key:b

keydown: code:104, key:8
keyup : code:104, key:h

keydown: code:105, key:9
keyup : code:105, key:i

Normally I would use keypress, and as such, have never had any problems. I came across this when highlighting numpad representative buttons on the screen when the corresponding numpad key was pressed on the keyboard (highlight on down, and remove highlight on up).

Any ideas?


Solution

  • There is a big mess in how different browsers implement keydown, keypress and keyup events, even the keyCode values in keydown and keyup events are not yet standardized across browsers.

    Currently the event object has three properties that contain information about the pressed key:

    • charCode - the Unicode value of a character key pressed
    • keyCode - a number representing the key that user pressed
    • which - the keyCode or charCode number for an alphanumeric key pressed

    The value of pressed key is stored in either keyCode or charCode property, but never both, keyCode is always set in the keydown and keyup events, charCode is set in the keypress event.

    So, for example, if you press 'e':

    • keydown and keyup reports:
      • charCode=0, keyCode=69, which=69 - caracter at number 69 is capital letter E
    • keypress reports:
      • charCode=101, keyCode=0, which=101 - caracter at number 101 is small letter e

    And if you press number 9 in numpad:

    • keydown and keyup reports:
      • charCode=0, keyCode=105, which=105 - caracter at number 105 is small letter i
    • keypress reports:
      • charCode=57, keyCode=0, which=57 - caracter at number 57 is digit 9

    Mootools

    Mootools tries to standardise things by adding event.code and event.key properties:

    event.code = event.which || event.keyCode;
    event.key = String.fromCharCode(code).toLowerCase();
    

    It also converts keyCodes for the numbers on the numpad, but only for keydown event ( version 1.4.5 ), and not for keyup. I don't know if this is intentionally or not, but keyup event can be easily modified to have the same behaviour by replacing the line 1163 in mootools-core-1.4.5-full-nocompat.js from:

    if (type == 'keydown') {
    

    to:

    if (type == 'keydown' || type == 'keyup') {
    

    That way keyCodes in keyup event will be also converted.



    Interestingly, the Mozilla Developer Network says:

    'charCode', 'keyCode' and 'which' is deprecated, you should use 'char' or 'key' instead, if available.

    But I don't see that implementation in Firefox or Chrome yet. And jQuery adds ‘key’ property to an event object, but it is always 'undefined' ( probably depends on browser implementation ).