如何实现输入框逐字母双向过滤名称列表(支持退格实时刷新)
问题背景
这是对往期逐字符过滤列表相关问题的跟进提问。
当前使用的脚本支持逐字符输入名称时过滤排除不匹配的列表选项,但退格删除1-2个字符时,无法基于剩余输入内容重新展示匹配项,必须清空输入框所有内容才能重新加载完整列表。
对应列表示例片段:
<li>New Brunswick</li> <li>New Hampshire</li> <li>New Jersey</li> <li>New Mexico</li> <li>New York</li>
- 场景举例:如果误输入
New G而非目标的New H,仅删除字母G和前置空格无法重新展示所有以New开头的选项,必须清空全部输入内容,等待包含63个州、省、地区的完整列表重新加载后从头开始输入,操作成本很高。 - 目标效果:根据输入框内剩余字符实时重新渲染匹配的列表项。
当前使用的脚本代码如下:
function myFunction() { var value = document.getElementById("myInput").value.toUpperCase(); var myUL = document.getElementById("myUL"); for (var elem of myUL.getElementsByTagName("li")) { if (elem.innerText.toUpperCase().startsWith(value)) { elem.style.display = ""; } else { elem.style.display = "none"; } } }
解决方案
现有过滤逻辑本身没有问题,出现退格后列表不更新的核心原因是输入框的事件绑定错误:大概率你只给输入框绑定了keypress或keydown事件,这类事件无法覆盖退格删除、内容剪切、输入法输入等所有内容变更场景。
只需要把输入框的触发事件替换为input事件,即可在输入内容发生任何变化时(包括输入、退格、粘贴、剪切、输入法选词等)自动触发过滤逻辑,无需修改核心过滤代码。
具体修改方式
- 如果是在HTML标签上直接绑定事件,把原有事件属性替换为
oninput:
<input type="text" id="myInput" oninput="myFunction()">
- 如果是通过JS动态绑定事件,修改事件监听参数:
document.getElementById("myInput").addEventListener('input', myFunction);
可选性能优化
如果列表项数量较多,可以给过滤逻辑增加防抖处理,避免频繁操作时反复遍历DOM造成卡顿:
let filterTimer = null; function myFunction() { clearTimeout(filterTimer); filterTimer = setTimeout(() => { const inputValue = document.getElementById("myInput").value.toUpperCase().trim(); const listItems = document.getElementById("myUL").getElementsByTagName("li"); for (const item of listItems) { item.style.display = item.innerText.toUpperCase().startsWith(inputValue) ? "" : "none"; } }, 80); }
修改完成后,所有输入变更场景都会实时基于当前输入值过滤匹配列表项,不需要再清空输入框重载完整列表。
内容的提问来源于stack exchange,提问作者Ean
相关产品推荐
相关产品推荐

