以下代码片段在 chrome/edge/safari 中运行良好。在 Firefox 中,textarea
获得焦点,但按下的字符不会添加到 textarea
- 第一个字符将始终丢失。
document.addEventListener('keypress', (event) => {
document.querySelector('#input').focus();
});
<textarea id="input"></textarea>
如何才能使其在所有浏览器中表现一致?
最佳答案
以下是如何让它在没有浏览器嗅探的情况下工作:当按键发生时,将处理程序绑定(bind)到文本区域上的 input
事件,并设置 0 毫秒超时。
如果浏览器接受了文本区域的按键,input
处理程序将在超时之前运行(因为 input
事件同步触发)。如果发生这种情况,您就知道浏览器已正确处理按键,并且您可以取消超时。
然后,如果超时触发,您就知道 input
事件尚未触发,因此该字符尚未添加到文本区域,您可以这样做以编程方式进行。
在事件处理程序和超时处理程序中,您都可以取消绑定(bind)事件处理程序 - 它最多应该运行一次(每次按键)。
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();
});
<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>
如果您在 Firefox 中尝试上述代码片段,控制台会显示“超时已触发”。在所有其他浏览器中,它会显示“输入事件”。无论哪种情况,您按下的键都会添加到文本区域。
一些注意事项:
从技术上讲,为了保持行为一致,您需要做的不仅仅是将字符附加到末尾;您还必须查看光标位置和文本选择等内容。然而,这可能有点矫枉过正。
如果您需要支持非常旧的浏览器,您可能需要对
input
事件的可用性进行功能检查。如果您有其他代码依赖于按键时同步更改文本区域,您可能必须在那里进行更新。
关于javascript - 在按键事件处理程序中聚焦文本区域元素时,Firefox 出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45598256/