JavaScript按退格键聚焦输入框前一个兄弟节点需按两次的问题
问题复现
现有name属性为box的输入框,已实现输入后自动切换下一节点焦点的功能,代码如下,运行正常:
box.addEventListener('input', function () { if(!isNaN(parseInt(box.value))){ box.value = ""; }else if(box != null){ box.nextSibling.focus(); } });
需要新增退格键聚焦前一个兄弟输入节点的功能,初始实现代码如下:
box.addEventListener('keyup', function (e) { if(e.key == 'Backspace' && box != null){ box.previousSibling.focus(); } })
该实现存在异常:仅第一次按退格键可正常跳转焦点,其余场景需要连续按两次退格键才能完成焦点切换,更换为keydown事件绑定也未解决问题。
故障原因
两个问题导致该异常:
- 未做输入框内容状态判断:当输入框内存在残留内容时,第一次按退格键只会触发浏览器默认的内容删除行为,不会执行焦点跳转,等内容被清空后第二次按退格才会触发跳转逻辑,因此表现为需要按两次
- 节点获取方式有误:
nextSibling/previousSibling会匹配DOM结构中的空白文本节点(代码换行、缩进产生的不可见节点),这类节点不存在focus方法,会导致偶发的焦点调用失败
修复代码
直接替换原有事件绑定逻辑即可:
// 输入后自动跳转下一节点 box.addEventListener('input', function () { if(!isNaN(parseInt(box.value))){ box.value = ""; }else if(box) { const nextInput = box.nextElementSibling; nextInput && nextInput.focus(); } }); // 退格跳转上一节点 box.addEventListener('keydown', function (e) { if(e.key === 'Backspace' && box && box.value === '') { const prevInput = box.previousElementSibling; if(prevInput) { e.preventDefault(); prevInput.focus(); } } })
逻辑说明
- 退格跳转逻辑增加
box.value === ''判断,仅当当前输入框已经为空时按退格才触发焦点跳转,符合常规输入交互,不会出现需要按两次的问题 - 用
nextElementSibling/previousElementSibling替代原有兄弟节点获取方法,仅匹配元素节点,避免取到空白文本节点导致的焦点调用失败 - 事件绑定选用
keydown,跳转前调用e.preventDefault()阻止退格键默认行为,避免出现页面回退等非预期表现
内容的提问来源于stack exchange,提问作者Heena Mirchandani
相关产品推荐
相关产品推荐

