移动端Web中keydown、keyup事件如何正确获取按键key值
问题根因
移动端虚拟键盘的keydown、keyup事件属于兼容性重灾区,安卓端各大浏览器的实现普遍不符合W3C标准:
- 系统自带输入法、第三方输入法的预输入、联想词逻辑会拦截原始按键事件
- 绝大多数厂商没有在
keydown/keyup事件中正确填充e.key属性,才会出现Process、Unidentified这类异常返回值
修复方案
根据你的业务场景可以选择以下两种兼容方案:
方案1:仅需要获取输入框输入内容(最稳妥)
优先用input事件替代键盘事件,这是移动端兼容性最好的方案,支持所有输入场景(虚拟键盘输入、手写、语音输入、粘贴等):
const inputElement = document.querySelector("input"); const inputList = document.getElementById("inputList"); inputElement.addEventListener("input", (e) => { const li = document.createElement("li"); // 获取输入框当前完整值 li.innerText = e.target.value; // 如果需要获取本次输入的内容,可以用以下写法 // li.innerText = e.data || ''; inputList.appendChild(li); });
对应的HTML结构可以简化为:
<h2>输入框</h2> <input type="text"> <h2>输入内容记录</h2> <ul id="inputList"></ul>
方案2:需要监听回车、删除等特殊按键
可以组合使用beforeinput事件的inputType属性识别操作类型,同时对keyCode做兜底兼容:
const inputElement = document.querySelector("input"); const keydownList = document.getElementById("keydownList"); inputElement.addEventListener("keydown", (e) => { let keyVal = e.key; // 移动端异常值兜底 if (keyVal === 'Process' || keyVal === 'Unidentified') { // 常用特殊按键keyCode映射 const keyMap = { 8: 'Backspace', 13: 'Enter', 27: 'Escape', 37: 'ArrowLeft', 38: 'ArrowUp', 39: 'ArrowRight', 40: 'ArrowDown' }; keyVal = keyMap[e.keyCode] || 'Unknown'; } const li = document.createElement("li"); li.innerText = keyVal; keydownList.appendChild(li); }); // 也可以用beforeinput事件识别操作类型 inputElement.addEventListener("beforeinput", (e) => { if (e.inputType === 'deleteContentBackward') { // 触发删除操作 } else if (e.inputType === 'insertLineBreak') { // 触发回车换行操作 } });
注意事项
如果你的需求是实现快捷键类功能,移动端尽量不要依赖键盘事件,改用UI交互替代会更稳妥,比如增加自定义提交按钮代替回车提交,可以避免90%以上的兼容问题。
内容的提问来源于stack exchange,提问作者Script Raccoon
相关产品推荐
相关产品推荐

