Key codes are the foundation of keyboard input and event handling in JavaScript. By assigning an integer value to each physical key, developers can detect keyboard input and react programmatically. Understanding key codes is essential both for processing user input and creating accessible applications.

What Are Key Codes?

Key codes are part of the JavaScript KeyboardEvent interface, which represents keyboard events in the Document Object Model (DOM). The keydown and keyup events fire whenever a key is pressed or released. These events contain a keyCode property corresponding to the physical key triggered by the user.

For example:

keydown Event -> keyCode Property = 65 (Key: A)

Key codes follow several common conventions:

  • Alphanumeric keys have consecutive values starting from 65 for letter ‘A‘
  • Special keys like Enter, Tab, Space have distinct non-consecutive values
  • Modifier keys like Shift, Ctrl have different key codes per browser

This allows JavaScript to uniquely identify which key on the keyboard was pressed for any given KeyboardEvent. The keyCode itself is an integer without any direct meaning. Developers must refer to key code reference tables to match integers to physical keys.

Detecting Key Presses with Key Codes

The main purpose of key codes in JavaScript is to enable programmatic detection of key presses. By comparing keyCode values, you can trigger custom actions for specific keys.

For example, detecting the Enter key:

document.addEventListener(‘keydown‘, (event) => {
  if(event.keyCode === 13) { // 13 = Enter key
    submitForm(); // Custom submit logic
  }
});

Some common key detection use cases:

  • Accessibility – e.g. alert screen reader on Enter
  • Input validation – e.g. restrict invalid characters
  • Keyboard shortcuts – e.g. Ctrl + S to save
  • Games – e.g. spacebar to jump

You can directly access keyCode on any KeyboardEvent:

function printKeyCode(event) {
  console.log(event.keyCode);  
}

document.addEventListener(‘keyup‘, printKeyCode);

See a live demo of logging key codes here.

Complex Action Detection

For advanced shortcut combinations like Ctrl + Alt + G, you need to check multiple modifier keys along with the main key‘s keyCode:

function handleComplexShortcut(event) {

  if(event.ctrlKey && event.altKey && event.keyCode === 71) {
    // Ctrl + Alt + G
  }  

}  

This allows JavaScript to support even complex multi-key pressed actions.

Limitations of Key Codes

While key codes enable wide range of capabilities, they come with certain limitations:

  1. No distinction between uppercase and lowercase – A and a have same keyCode
  2. Inconsistent special key support across browsers
  3. Deprecated in favor of KeyboardEvent.key standard

For text input, relying solely on keyCode is not enough. The Clipboard API and other alternatives must be used as well.

How Keys Get Assigned Key Codes

Under this integer-based system, how do keys get mapped to key codes? The assignment process has evolved over time alongside changing web standards:

1. Physical Keyboard Scan Codes

The first source of key codes was the PC keyboard scan code system. This refers to the underlying hardware signals sent by pressing keys to the computer‘s keyboard controller. These scan codes got directly mapped to JavaScript event keyCode values in early browsers.

However, scan codes are not consistent across different keyboard manufacturers. Additional translation was needed to provide a common layout for web application purposes.

2. USB HID Usage Tables

To standardize the meanings, usages were defined for each key in the USB Human Interface Device standards documents. These "HID usages" representing common keys made up the bases for JavaScript key codes we use today.

Browser vendors added support for translating different keyboard scan codes into consistent HID usage-based keyCodes. This ensured web developers could rely on uniform values across different hardware.

3. W3C Key Event Specifications

As JavaScript programming matured and usage grew, browser vendors faced pressure to fix inconsistencies in their key code implementations. The W3C DOM Level 3 Events standard formally specified listings to ensure interoperable values across all major engines.

However these standards were framed late, so real-world key code usage still varies:

Key     | Firefox | Chrome | IE/Edge 
-------------------------------------------
Ctrl     | 224     | 17     | 17     
Shift    | 16      | 16     | 16       
Meta (Win)| 224    | 91     | 91/93

Win/Super key is a prime example of ongoing fragmentation. Newer proposals like KeyboardEvent.code aim to build common abstractions atop the legacy keyCode system.

Use Cases Enabled by Key Codes

Beyond basic input handling, knowledge of key codes unlocks several advanced application capabilities:

1. Custom Keyboard Shortcuts

JavaScript APIs allow capturing keyboard events before the browser. This enables defining application-specific shortcut behaviors using key codes:

document.addEventListener(‘keydown‘, (event) => {
  if(event.ctrlKey && event.keyCode === 83) { 
    event.preventDefault(); 
    app.saveDocument();
  }
});  

Typically prevented default browser behavior using event.preventDefault() to avoid conflicts.

Common examples:

  • Games listening for WASD keys
  • Rich text editors mimicking Windows/OSX shortcuts
  • Web-based code editors with programming hotkeys

2. Optimized Data Entry Workflows

For data entry scenarios like forms, key codes power various optimizations:

  • Auto-tab focus flows form field to field on Enter
  • Allow characters only from whitelist of permitted keys
  • Move focus outside certain numeric inputs on arrow keys

All based on reacting to permitted keyCode values.

3. Accessibility Features

Assistive technology for disabled users often relies on keyboard navigation and shortcuts. Efficient key code usage ensures web accessibility:

  • Add aria-keyshortcuts for screenreaders
  • Ensure right-arrow moves natural document flow
  • Don‘t visually update on modifier keys to avoid seizures

Poor practices like lack of Escape handling drastically degrade handicapped experiences.

Alternatives and Evolution of Key Codes

Despite their wide usage, even key codes cannot fully address complex modern input patterns:

  • Internationalization – keyCode 65 means different Glyphs based on keyboard locale
  • Mobile/tablets – No concept of physical keys
  • Speech/handwriting recognition – Requires higher level abstractions

KeyboardEvent.key replacing keyCode

To cater to these needs, the DOM Standard introduced KeyboardEvent.key property that aims to eventually replace keyCode.

.key provides not the physical key, but Unicode output character allowing all modern IME and typing workflows. However, it remains a working draft with inconsistent real-world support as of 2023.

The key value itself poses certain trade-offs around privacy and localization as well. It is not a transparent indicator of user intent anymore – scrolling a zoomed page fires different arrows than natural arrow keys for example.

Long term evolution

Eventually as input mechanisms evolve beyond physical keyboards, and as internationalization needs grow, keyCode will fade out from common usage. New event attributes focused purely on semantic meaning of "user intent" are emerging – like clickCount, code, and location.

However, none yet provide the simplicity and widespread support of raw keyCode values. For most application code even today, directly accessing keyCode remains the pragmatic approach.

Best Practices for Key Code Usage

While moving away from key codes in future, what best practices should JS developers follow for robust behavior today?

Cross Browser Support

Legacy browser quirks around old IE versions, Safari macOS, and Firefox Linux require multiple key codes tested per physical key:

// Cover different Shift key codes 
if (event.keyCode === 16 || event.keyCode === 10) {
  // Handle shift keydown
}

Prefer checking for raw key code over event type – firefox focuses button on space/enter, so keyup better than click.

Feature Detection Not Browser Detection

Rather than changing logic based on IE vs Chrome, dynamically check if required events or properties work as intended:

if (‘KeyboardEvent‘ in window && ‘keyCode‘ in window.KeyboardEvent) {
  // Can rely on keyCode 
}

This maximizes compatibility across both old and future speculative browsers.

Use Libraries Like Lodash

Standards like Lodash or Modernizr provide cross-platform implementations hiding key code discrepancies behind helper functions:

_.isFunction(window.KeyboardEvent.keyCode) // Check support

Builds resilience against specification changes as well.

Prefer Semantic Checking Over Raw Values

Rather than numeric values for Enter or Space that vary across locales, use intention-revealing checks:

// Behavioral checks are clearer  
const isHorizontalMovement = 
  event.keyCode === 37 || // left arrow 
  event.keyCode === 39; // right arrow

This improves readability and maintainability.

Plan Graceful Deprecation Paths

Given the shifting standards space around key events, avoid hard dependencies on current keyCode behavior alone. Structure code and architectures to simplify replacing raw checks with newer abstractions over time:

function handleKeyEvent(event) {

  const keyHandler = getKeyHandler(event.keyCode); 

  keyHandler.handleEvent(event);

}

// Can redirect handlers over time  
function getKeyHandler(keyValue) {

  if (keyValue === 13) {
    return enterHandler; 
  }  
  // ...
}

This way adoption of new paradigms will require minimal change to application logic down the line.

Key Code Support and Values Across Browsers

Despite standardization initiatives, practical key code implementation continues fragmented across user agents. For real-world usage, developers need visibility into exactly which keys behave reliably on their target browsers.

Below charts summarize handling for common alpha-numeric and special keys that make up typical keyboard shortcuts:

Alpha-numeric Key Code Support

Key Chrome Firefox Safari IE11
A Yes Yes Yes Yes
B Yes Yes Yes Yes
C Yes Yes Yes Yes
D Yes Yes Yes Yes
E Yes Yes Yes Yes
F Yes Yes Yes Yes
G Yes Yes Yes Yes
H Yes Yes Yes Yes
I Yes Yes Yes Yes
J Yes Yes Yes Yes
K Yes Yes Yes Yes
L Yes Yes Yes Yes
M Yes Yes Yes Yes
N Yes Yes Yes Yes
O Yes Yes Yes Yes
P Yes Yes Yes Yes
Q Yes Yes Yes Yes
R Yes Yes Yes Yes
S Yes Yes Yes Yes
T Yes Yes Yes Yes
U Yes Yes Yes Yes
V Yes Yes Yes Yes
W Yes Yes Yes Yes
X Yes Yes Yes Yes
Y Yes Yes Yes Yes
Z Yes Yes Yes Yes

Alphabet keys are supported and consistent across environments, but lacking Unicode support.

Special Key Code Behavior

Key Chrome Firefox Safari IE11
Space 32 32 32 32
Enter 13 13 76 13
Backspace 8 8 8 8
Delete 46 46 8 46
Tab 9 9 48 9
Escape 27 27 27 27
Ctrl 17 224 59 17
Shift 16 16 56 16
Alt 18 18 55 18
Meta/Windows 91 224 91 91/93
Arrows Yes Yes Yes Yes

Edge cases remain around modifier keys, enter handling, and Windows key differences.

Consult comprehensive key code testers like keycode.info for full matrix details.

Frequently Asked Questions

We‘ll address some common key code related doubts that JavaScript developers face:

1. Why do different keyboard have different hardware key codes?

Keyboard scan codes originated independently based on keyboard manufacturer device drivers before USB standardization. Their digital communication protocols were never intended for reliable software usage across keyboards.

2. What is the sequence – keydown, keypress, keyup?

As per the UI Events spec, the order of the sequence is – keydown, followed by multiple keypress, concluded by a keyup. keypress represents the time when a character is generated, while text input happens later.

3. Which key names work cross-browser?

While alumni-numeric keys like a or 7 work across browsers, for special keys rely on aliases defined in specs – ArrowLeft over Left. Some libraries provide normalized names as well.

4. Why don‘t key events work consistently for some keys?

Legacy browser event models were built atop ad hoc extensions to capture user input instead of standardized components. So for advanced handling, robust abstractions are necessary over raw events.

5. Can javascript change what happens on a keypress?

Yes, via event.preventDefault() a handler can bypass default browser behaviors, stop event propagation, and define custom reactions for key events.

6. What is an example of disabling key combinations?

Use event modifiers to restrict specific shortcut combinations:

function blockCtrlT(e) {
  if (e.ctrlKey && e.key === ‘t‘) { 
    e.preventDefault();
  }
}

document.addEventListener(‘keydown‘, blockCtrlT);

Prevents opening a new tab via Ctrl + T.


For even more questions around browser-specific handling, debugging issues, creating custom bindings, and architectural decisions – please refer to the complex examples in the W3C specification itself at DOM Level 3 KeyboardEvent key Code.

Conclusion

Key codes form the basic vocabulary that allows JavaScript to understand keyboard input and react programmatically. By assigning integer values to keys, the keydown and keyup events enable detecting specific presses to trigger custom logic in applications.

Key codes support essential programming needs like data entry constraints, accessibility features and custom shortcuts. However, legacy browser discrepancies around key values still persist due to long evolution. Features like KeyboardEvent.key aim to provide an improved abstraction.

As a full stack developer relying extensively on keyboard UIs, being familiar with key code interfaces allows building robust input handling logic even today. Through intention-revealing checks and careful feature detection, JavaScript applications can leverage standards like keyCode while being ready for coming advances in input event processing.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *