Search code examples
javascripteventsonkeyuponkeypress

Using Javascript, how can I detect a keypress event but NOT when the user is typing in a form field?


On my Web site, I want to open my search form dynamically when a user hits the question mark key. I can do that using the following code:

document.onkeyup = checkKey;
function checkKey(evt) {
    evt = evt || window.event;
    if (evt.keyCode == '191') { // user inputs the "?" key [shift + /]
        // Do something
    }
}

However, I don't want to trigger the action if the user is simply typing a question mark in a comment field or search field. For example, in Gmail you can hit "?" to open keyboard shortcuts overlay, but if you are composing an email and type a "?" the shortcuts don't open.

How can I detect a keypress event but NOT when the user happens to be typing in a form field?


Solution

  • Sniffing on the event target property's tagName would perhaps be sufficient. The below obviously isn't exhaustive-- there's several edge cases to consider-- but it's a start. Try typing when in the form elements and then just when focused elsewhere in the document:

    document.onkeyup = checkKey;
    function checkKey(evt) {
        const formElements = ['INPUT', 'TEXTAREA', 'SELECT', 'OPTION'];
        evt = evt || window.event;
        if (formElements.includes(evt.target.tagName)) {
          console.log('ignore me!');
        } else {
          console.log('do something!');
        }
    }
    <h1>my form</h1>
    <form>
      <label for="name">name</label>
      <input id="name" name="name" />
      <br/>
      <label for="aboutme">about me</label>
      <textarea id="aboutme" name="aboutme"></textarea>
      <br/>
      <label for="ghostbuster">ghostbuster</label>
      <select id="ghostbuster" name="ghostbuster">
        <option value="winstonzeddmore">Winston Zeddmore</option>
        <option value="egonspangler">Egon Spangler</option>
        <option value="petervenkman">Peter Venkman</option>
        <option value="raystanz">Ray Stanz</option>
      </select>
    </form>
    
    <p> some text</p>