键盘导航选中自动补全项按回车时页面跳转至NotFound问题排查
问题
实现支持自动补全的机场代码及城市输入框,提供三种选择建议项的方式:鼠标点击选中、Tab切换选中、键盘箭头导航选中后按回车确认。前两种方式正常,但第三种操作会导致Codepen页面跳转显示“Not Found”。
HTML代码:
<form> <input autocomplete="off" name="user-input" class="suggest" placeholder="City or airport code"/> </form>
JS监听键盘事件代码(activeNumber表示建议列表中当前选中项的索引,仅箭头导航时值≥0):
document.addEventListener("keydown", function(e) { let list = document.querySelector('.autocomplete-list'); if (!list) { return; } list = list.querySelectorAll('.list-item'); // enter if (e.keyCode === 13) { if (activeNumber < 0) { e.target.click(); } else { list[activeNumber].click(); } } else if (e.keyCode == 40) { activeNumber++; changeActive(list); } else if (e.keyCode == 38) { activeNumber--; changeActive(list); } })
注:Tab选中项后按回车调用click()能正常工作,排除点击监听器本身的问题。
原因分析
用箭头导航选中建议项后按回车时,浏览器默认的表单提交行为未被阻止。虽然代码调用了list[activeNumber].click(),但浏览器会同时触发表单的submit事件;由于表单未指定action属性,浏览器会默认提交到当前页面地址,导致Codepen页面跳转并显示“Not Found”。
而Tab选中项时,焦点在建议项本身,按回车触发的是建议项的点击事件,此时表单不会触发默认提交(焦点不在输入框或表单提交控件上),因此不会出现跳转问题。
解决方案
在回车事件处理逻辑中添加e.preventDefault(),阻止浏览器的默认表单提交行为:
修改后的JS代码:
document.addEventListener("keydown", function(e) { let list = document.querySelector('.autocomplete-list'); if (!list) { return; } list = list.querySelectorAll('.list-item'); // enter if (e.keyCode === 13) { // 阻止默认表单提交行为 e.preventDefault(); if (activeNumber < 0) { e.target.click(); } else { list[activeNumber].click(); } } else if (e.keyCode == 40) { activeNumber++; changeActive(list); } else if (e.keyCode == 38) { activeNumber--; changeActive(list); } })
额外建议:优先使用e.key替代已废弃的e.keyCode,比如判断回车用e.key === 'Enter',上下箭头用e.key === 'ArrowDown'和e.key === 'ArrowUp',提升代码兼容性。
内容的提问来源于stack exchange,提问作者Natalie
相关产品推荐
相关产品推荐

