将keytarea元素聚焦在keypress事件处理程序时,Firefox会出现问题

时间:2017-08-09 18:34:28

标签: javascript html firefox

以下代码段适用于chrome / edge / safari。在Firefox中,textarea会得到关注,但被压缩的字符不会被添加到textarea中 - 第一个字符将始终丢失。



document.addEventListener('keypress', (event) => {
  document.querySelector('#input').focus();
});

<textarea id="input"></textarea>
&#13;
&#13;
&#13;

如何在所有浏览器中保持一致?

2 个答案:

答案 0 :(得分:2)

以下是如何在没有浏览器嗅探的情况下使其工作:当按键发生时,将处理程序绑定到textarea上的input事件,并设置0毫秒超时。

如果浏览器接受了textarea的按键,input处理程序将在超时之前运行(因为input事件同步触发)。如果发生这种情况,您知道浏览器已正确处理了按键,您可以取消超时。

然后,如果超时触发,你知道input事件没有被触发,因此字符没有被添加到textarea,而你以编程方式进行。

在事件处理程序和超时处理程序中,取消绑定事件处理程序 - 它应该最多运行一次(每次按键)。

&#13;
&#13;
var textarea = document.getElementById("input");

document.addEventListener("keypress", function (event) {
  if (event.target === textarea) {
    return;
  }
  
  var eventHandler = function () {
    textarea.removeEventListener("input", eventHandler);
    clearTimeout(timeoutId);
    console.log("input event");
  }

  var timeoutHandler = function () {
    var character = ("char" in event) ? event.char : String.fromCharCode(event.charCode);
    textarea.value += character;
    textarea.removeEventListener("input", eventHandler);
    console.log("timeout fired");
  }

  timeoutId = setTimeout(timeoutHandler, 1);
  textarea.addEventListener("input", eventHandler);
  textarea.focus();
});
&#13;
<textarea id="input"></textarea>
<p style="background: #ccc">
  <b>Click here</b> to make sure the document is focused, but the textarea is not. Then press a key.
</p>
&#13;
&#13;
&#13;

如果您在Firefox中尝试上述代码段,控制台会说&#34;超时已触发&#34;。在所有其他浏览器中,它会说&#34;输入事件&#34;。在任何一种情况下,您按下的键都会添加到textarea。

一些注意事项:

  • 从技术上讲,为了保持一致的行为,你需要做的不仅仅是将角色追加到最后;您还需要查看光标位置和文本选择等内容。然而,这可能是过度的。

  • 如果您需要支持真正的旧浏览器,您可能需要对input事件的可用性进行功能检查。

  • 如果您有其他代码依赖于textarea在按键时同步更改 ,您可能需要在那里进行更新。

答案 1 :(得分:1)

如果任何其他浏览器与Firefox共享相同的行为,此代码将,但以下代码将添加任何键输入,因为它是一个字符,当代码在 Firefox 上运行时,字符串长度为1:

&#13;
&#13;
<textarea id="input"></textarea>
&#13;
destroy_all
&#13;
&#13;
&#13;

再次请注意,这并不能保证它能够在所有浏览器中运行,因为这是Firefox的一个特定修复,但是,如果您在其他浏览器中看到相同的行为,我使用了从这篇SO帖子中回答,检测客户端正在使用的当前浏览器(假设它在本帖讨论的浏览器列表中):How to detect Safari, Chrome, IE, Firefox and Opera browser?