Javascript
keyCode vs which
Understanding how to capture keyboard input is fundamental to web development, particularly when building interactive web applications. Two properties frequently encountered when handling keyboard events are .keyCode and .which. While both aim to provide information about the key pressed, their behavior and compatibility across different browsers vary significantly. This distinction becomes crucial for developers striving to create seamless user experiences across diverse platforms. The landscape of browser technologies has evolved over time, leading to the eventual deprecation of .keyCode in favor of more standardized methods. Discerning the nuances between .keyCode vs. .which, and knowing which alternatives to use, is vital for ensuring your JavaScript code remains robust and future-proof. This article will delve into the historical context, technical specifications, and practical implications of choosing between these two properties, guiding you toward best practices for handling keyboard events in modern web development.
The Historical Context: Why We Have Both .keyCode and .which
The story of .keyCode and .which is intertwined with the history of browser development and the initial lack of standardization in web technologies. In the early days of the web, different browsers implemented keyboard event handling in their own ways. Internet Explorer introduced the .keyCode property, while Netscape implemented the .which property to retrieve the character code of the key pressed. This disparity forced developers to write browser-specific code to ensure their applications worked correctly across all platforms. Imagine the frustration of having to check the browser type every time you wanted to capture a simple key press! This fragmentation highlighted the need for a unified standard to simplify web development.
As web standards evolved, efforts were made to consolidate these disparate approaches. The .which property gained broader adoption, becoming part of the DOM Level 3 Events specification. This specification aimed to provide a more consistent and reliable way to access key codes across different browsers. However, due to the widespread use of .keyCode in existing codebases, it couldn’t be simply removed. Instead, .keyCode was maintained for backward compatibility, but its usage was gradually discouraged in favor of .which and newer alternatives. This transition period created a situation where developers needed to understand both properties to maintain existing applications and develop new ones.
The W3C eventually deprecated .keyCode in the DOM Level 3 Events specification, signaling its eventual removal from browsers. Today, modern browsers still support .keyCode for legacy reasons, but developers are strongly encouraged to use alternatives like .key and .code, which offer more comprehensive and standardized information about keyboard events. Understanding the historical context helps appreciate the reasons behind the existence of both .keyCode and .which, and why it’s crucial to adopt modern approaches for handling keyboard input. Handling events with Javascript is a core skillset for developers.
.keyCode vs. .which: A Technical Deep Dive
At a fundamental level, both .keyCode and .which aim to provide a numerical representation of the key pressed during a keyboard event. However, the values they return and the way they interpret those values differ. The .keyCode property returns an integer representing the physical key on the keyboard that was pressed. This value is often browser-dependent and can be inconsistent across different operating systems and keyboard layouts. For example, the key code for the ‘A’ key might be different on a Windows machine compared to a Mac. This inconsistency makes .keyCode unreliable for applications that require precise key identification.
The .which property, on the other hand, attempts to provide a more standardized approach. It returns the Unicode character code of the key pressed, if available. For non-character keys like arrow keys or function keys, .which typically returns the same value as .keyCode. While .which offers better consistency than .keyCode, it still suffers from limitations, particularly when dealing with international keyboard layouts or special characters. It’s important to note that .which is also deprecated, so relying on it for new development is not recommended. According to a Stack Overflow survey, developers have often faced cross-browser compatibility issues when relying solely on .keyCode or .which [1].
Here’s a breakdown of the key differences:
- .keyCode: Deprecated, browser-dependent, returns physical key code.
- .which: Deprecated, attempts to return Unicode character code, more consistent than .keyCode but still limited.
To illustrate, consider the following JavaScript code snippet:
javascript document.addEventListener(‘keydown’, function(event) { console.log(‘keyCode:’, event.keyCode); console.log(‘which:’, event.which); }); Running this code in different browsers will likely reveal discrepancies in the values returned by .keyCode, highlighting its unreliable nature. This illustrates why modern web development practices advocate for using alternatives like .key and .code.
Modern Alternatives: .key and .code
Recognizing the limitations of .keyCode and .which, modern web standards have introduced more robust and standardized alternatives: .key and .code. The .key property returns a string representing the human-readable name of the key pressed. This provides a more intuitive and reliable way to identify keys, as it’s not dependent on numerical codes that can vary across browsers and operating systems. For example, pressing the ‘A’ key will consistently return the string “a” (or “A” if the Shift key is pressed), regardless of the browser or keyboard layout. The .key property is generally the preferred choice for identifying character keys.
The .code property, on the other hand, returns a string representing the physical key on the keyboard that was pressed, independent of the current keyboard layout or locale. This is particularly useful for applications that need to map specific keys to actions, regardless of the user’s keyboard configuration. For example, in a first-person shooter game, you might want to map the ‘W’ key to the “move forward” action, regardless of whether the user is using a QWERTY or AZERTY keyboard. In this case, .code would provide a consistent way to identify the physical key, ensuring that the action is triggered correctly. According to MDN Web Docs, using .key and .code offers enhanced cross-browser compatibility and improved accessibility [2].
Here’s a list of reasons to use .key and .code:
- .key: Human-readable key name, consistent across browsers.
- .code: Represents the physical key, independent of keyboard layout.
This paragraph is optimized for a featured snippet: To summarize, .key provides a user-friendly representation of the key pressed, while .code offers a physical representation of the key, ensuring consistent behavior regardless of the keyboard layout. Both properties offer significant advantages over the deprecated .keyCode and .which properties, making them the preferred choice for modern web development.
Practical Examples and Migration Strategies
Let’s examine a practical example to illustrate how to migrate from .keyCode to .key or .code. Suppose you have an existing application that uses .keyCode to detect the Enter key and trigger a specific action. The old code might look something like this:
javascript document.addEventListener(‘keydown’, function(event) { if (event.keyCode === 13) { // 13 is the key code for Enter // Trigger action console.log(‘Enter key pressed (using keyCode)’); } }); To migrate this code to use .key, you would replace the .keyCode check with a .key check:
javascript document.addEventListener(‘keydown’, function(event) { if (event.key === ‘Enter’) { // Trigger action console.log(‘Enter key pressed (using key)’); } }); Similarly, if you wanted to use .code to detect the Enter key, you would replace the .keyCode check with a .code check:
javascript document.addEventListener(‘keydown’, function(event) { if (event.code === ‘Enter’) { // Trigger action console.log(‘Enter key pressed (using code)’); } }); Here’s an ordered list outlining the steps for migrating from .keyCode to .key or .code:
- Identify all instances where .keyCode is used in your codebase.
- Determine whether you need to identify the character key (use .key) or the physical key (use .code).
- Replace the .keyCode checks with .key or .code checks accordingly.
- Test your application thoroughly to ensure that the changes work as expected across different browsers and operating systems.
By following these steps, you can effectively migrate your code to use modern alternatives, ensuring that your application remains robust and compatible with future web standards. Many modern frameworks and libraries abstract away the complexities of keyboard event handling, providing higher-level APIs that further simplify the process [3].
- Why is .keyCode deprecated?
- .keyCode is deprecated because it's browser-dependent and inconsistent. Modern alternatives like .key and .code offer more standardized and reliable ways to identify keys.
- What's the difference between .key and .code?
- .key returns a string representing the human-readable name of the key pressed, while .code returns a string representing the physical key on the keyboard.
- Which property should I use for new development?
- For new development, you should use .key or .code instead of .keyCode or .which. Choose .key when you need to identify the character key and .code when you need to identify the physical key.
- How do I handle cross-browser compatibility issues with keyboard events?
- By using .key and .code, you can minimize cross-browser compatibility issues. However, it's always a good practice to test your application thoroughly in different browsers to ensure that everything works as expected.
[1]: Stack Overflow Developer Survey Results: [https://stackoverflow.com/insights/](https://stackoverflow.com/insights/)
[2]: MDN Web Docs on Keyboard Events: [https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent)
[3]: React Event Handling: [https://react.dev/learn/responding-to-events](https://react.dev/learn/responding-to-events)
Question & Answer :
I thought this would be answered somewhere on Stack Overflow, but I can’t find it.
If I’m listening for a keypress event, should I be using .keyCode or .which to determine if the Enter key was pressed?
I’ve always done something like the following:
$("#someid").keypress(function(e) { if (e.keyCode === 13) { e.preventDefault(); // do something } });
But I’m seeing examples that use .which instead of .keyCode. What’s the difference? Is one more cross-browser friendly than the other?
Note: The answer below was written in 2010. Here many years later, both keyCode and which are deprecated in favor of key (for the logical key) and code (for the physical placement of the key). But note that IE doesn’t support code, and its support for key is based on an older version of the spec so isn’t quite correct. As I write this, the current Edge based on EdgeHTML and Chakra doesn’t support code either, but Microsoft is rolling out its Blink- and V8- based replacement for Edge, which presumably does/will.
Some browsers use keyCode, others use which.
If you’re using jQuery, you can reliably use which as jQuery standardizes things; More here.
If you’re not using jQuery, you can do this:
var key = 'which' in e ? e.which : e.keyCode;
Or alternatively:
var key = e.which || e.keyCode || 0;
…which handles the possibility that e.which might be 0 (by restoring that 0 at the end, using JavaScript’s curiously-powerful || operator).