DEV Community

Johnny Turco
Johnny Turco

Posted on

Focus a Field Using JavaScript KeyboardEvents

If you don't already know, you can press the forward slash key / on Gmail, YouTube, and Google search result pages to focus your cursor back to the search field. I'll show you how you can implement this on your website with JavaScript, and a few things to look out for.

First, you'll need reference to the search field you want to focus, in my case:

const searchField = document.querySelector('#search-input');
Enter fullscreen mode Exit fullscreen mode

We'll come back to this later.

Second, you'll need to add an EventListener. I would suggest adding the EventListener to the window EventTarget so the keyboard shortcut works anywhere on your webpage:

window.addEventListener()
Enter fullscreen mode Exit fullscreen mode

Next, you will need to choose a listener to listen for your keyboard shortcut. You have a few main choices:

  1. keydown
  2. keypress
  3. keyup

You should avoid using keypress because it has been deprecated, per MDN.

As their names suggest, keydown fires when the key is pressed and keyup fires when the key is released. Note that keydown will continue to fire for as long as the key is held down (keypress does, too). If you want to avoid the possibility of a bunch of unwanted characters in your focused input area, you may want to use keyup instead. Interestingly, Google will let you input as many forward slashes as you want if you hold down the key.

Another behavior to consider is the order the that the listeners fire. Because keydown fires on, well, key down, it fires before keyup. That difference may be obvious, but it can cause a noticeable delay if your users hold the shortcut key down for longer than a quick press. That said, the difference will probably be imperceptible to most. In my example, though, I'll use keyup:

window.addEventListener('keyup', (event) => {
    // code
})
Enter fullscreen mode Exit fullscreen mode

KeyboardEvent objects have a number of important properties. You can use .code or .key to specify which key to act on. MDN makes an important note about .code: this property ignores keyboard layout; it returns the code for the physical key location. So, if you have users that may be using Dvorak or other non-QWERTY keyboard layouts, you may need to consider how that affects their experience.

To determine which .code value corresponds to which character, check out this MDN doc. A list of .key values is provided at this doc.

Combining .code and all of the above with an if statement gets us a basic implementation:

const searchField = document.querySelector('#search-input');
window.addEventListener('keyup', (event) => {
  if(event.code === 'Slash'){
    searchField.focus();
  }
})
Enter fullscreen mode Exit fullscreen mode

The .focus() method focuses on the query selector we made in the first step.

There are a couple of other things we can add, though—some of which will be a matter of preference or depend on your implementation.

First, if your website has another text input besides your search field, you may want to disable the / shortcut (or whatever you set your shortcut key to) when entering text in the other input field. To do that, we first need to know what element the user is currently focused on, which can accomplished with the .activeElement property on the document.

We also need to know the name of the tag of the active element, which we can find with the aptly named .tagName property. Note that .tagName will return the element's tag name in all caps (e.g., an <input> tag will be returned as INPUT). Combined with .activeElement, the code looks like this:

document.activeElement.tagName
Enter fullscreen mode Exit fullscreen mode

Combined with our existing if statement, your code should look like this:

const searchField = document.querySelector('#search-input');
window.addEventListener('keyup', (e) => {
  if((e.code === 'Slash') && (document.activeElement.tagName !== 'INPUT')){
    searchField.focus();
  }
})
Enter fullscreen mode Exit fullscreen mode

If you're checking if your user is already in a text input field, you'll probably also want to check if the user is in a textarea field. You can accomplish this in the same way as above:

document.activeElement.tagName !== 'TEXTAREA'
Enter fullscreen mode Exit fullscreen mode

In total, the final product looks like this:

const searchField = document.querySelector('#search-input');
window.addEventListener('keyup', (e) => {
  if((e.code === 'Slash') && (document.activeElement.tagName !== 'INPUT') && (document.activeElement.tagName !== 'TEXTAREA')){
    searchField.focus();
  }
})
Enter fullscreen mode Exit fullscreen mode

Bonus: You may also want to check if your user is in an element that has the contenteditable HTML attribute enabled. The process to check is a little different, but also more straightforward with the .isContentEditable property. The property returns true if the contents are editable and false if not. contenteditable is of course less common than text inputs and text areas, but it's worth noting.

Top comments (0)