专注于具有文档级onkeydown事件的HTML元素

时间:2016-08-31 02:13:19

标签: javascript

当我按下' p'键,我想要一个特定的文本框成为焦点。为此,我在文档上设置了一个onkeydown监听器:

document.onkeydown = function(e) {
    // e.preventDefault();
    switch (e.key) {
        case 'p': {
            document.getElementById('test').focus();
            break;
        }
    }
}

当我按下' p'时,输入确实会获得焦点,但它也会输入字母' p'进入输入,我不想要。我只想把重点放在空文本框上。当我尝试将e.preventDefault添加到监听器时,这阻止了' p'从显示,但它也阻止我在文本框中输入任何内容。

如果没有输入快捷键,我如何专注于文本框?如果可能的话,我想在纯JavaScript中实现这一目标。

这里是JSFiddle:https://jsfiddle.net/qau6woL6/

2 个答案:

答案 0 :(得分:3)

仅在元素尚未聚焦时才更改焦点。此外,如果要更改焦点,则仅阻止默认值。这将允许您在第一个 p 用于设置焦点后,在<input>中键入 p

document.onkeydown = function(e) {
    var desiredEl = document.getElementById('test');
    if(desiredEl.contains(document.activeElement)){
        return;
    }
    switch (e.key) {
        case 'p': {
            e.preventDefault();
            if(window.InstallTrigger){
                //Is Firefox
                //Use setTimeout to work around a Firefox bug that prevents input
                //  if the focus is set here directly. Only noticed in Stack Overflow's
                //  snippet environment. Did not show up in JSFiddle. Not seen on
                //  Chrome. If the 250ms delay (100ms does not work) is unacceptable,
                //  then some other workaround can be found. Can shave to 200ms, but
                //  the minimal time required is undetermined. If that time varies by
                //   system performance is unknown. Bug seen on FF48.0.2 Win10x64.
                setTimeout(function(){
                    desiredEl.focus();
                },250);
            } else {
                desiredEl.focus();
            }
            break;
        }
    }
}
                       
<input id="test"></input>

Firefox问题:如果输入 p 并立即用desiredEl.focus();更改焦点,则设置焦点,但不能输入键盘。如果<input>中已有内容并且焦点被移动到其他位置,则可以通过键入 p 来返回键盘输入。

答案 1 :(得分:2)

聚焦字段后添加return false。正如评论中指出的那样,这将阻止p在字段中输入,即使它是集中的。因此,可能还需要检查焦点。

document.onkeydown = function(e) {
  switch (e.key) {
    case 'p':
      {
        var test = document.getElementById('test');
        if (document.activeElement !== test) { // Make sure it isn't focused already
          test.focus();
          return false;
        }
      }
  }
};
<input id="test" />