使用 Javascript,我如何才能检测到按键事件,而不是当用户在表单字段中输入时检测不到?

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

在我的网站上,我想在用户点击问号键时动态打开我的搜索表单。我可以使用以下代码来做到这一点:

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

但是,如果用户只是在评论字段或搜索字段中键入问号,我不想触发操作。例如,在 Gmail 中你可以点击“?”打开键盘快捷键覆盖,但如果您正在撰写电子邮件并键入“?”快捷方式打不开。

我怎样才能检测到按键事件,而不是当用户恰好在表单字段中输入时检测不到?

在您的 checkKey 函数中,您可以访问事件对象。您可以检查事件的目标以确定如何处理它。在这种情况下,您可以将示例修改为如下所示:

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

嗅探事件 target 属性 的 tagName 可能就足够了。下面显然不是详尽无遗的——有几个边缘情况需要考虑——但这是一个开始。尝试在表单元素中键入 when,然后在文档的其他地方聚焦时键入:

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>