如何实现输入字符后才显示自动补全列表并按输入内容过滤
电话本搜索功能问题修复
问题现象
当前实现的电话本搜索自动补全存在不符合预期的表现:用户尚未在输入框键入任何内容时,所有联系人词条就已经全部展示。
期望实现效果:联系人列表默认保持隐藏状态,仅当用户开始输入字符后才展示列表,同时根据输入的内容实时过滤匹配的结果。
参考效果:
原有完整代码
HTML结构
<h2>My Phonebook</h2> <input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name"> <ul id="myUL"> <li><a href="#">Adele</a></li> <li><a href="#">Agnes</a></li> <li><a href="#">Billy</a></li> <li><a href="#">Bob</a></li> <li><a href="#">Calvin</a></li> <li><a href="#">Christina</a></li> <li><a href="#">Cindy</a></li> </ul>
JavaScript逻辑
function myFunction() { var input, filter, ul, li, a, i, txtValue; input = document.getElementById("myInput"); filter = input.value.toUpperCase(); ul = document.getElementById("myUL"); li = ul.getElementsByTagName("li"); for (i = 0; i < li.length; i++) { a = li[i].getElementsByTagName("a")[0]; txtValue = a.textContent || a.innerText; if (txtValue.toUpperCase().indexOf(filter) > -1) { li[i].style.display = ""; } else { li[i].style.display = "none"; } } }
CSS样式
* { box-sizing: border-box; } #myInput { background-image: url('/css/searchicon.png'); background-position: 10px 12px; background-repeat: no-repeat; width: 100%; font-size: 16px; padding: 12px 20px 12px 40px; border: 1px solid #ddd; margin-bottom: 12px; } #myUL { list-style-type: none; padding: 0; margin: 0; } #myUL li a { border: 1px solid #ddd; margin-top: -1px; /* Prevent double borders */ background-color: #f6f6f6; padding: 12px; text-decoration: none; font-size: 18px; color: black; display: block } #myUL li a:hover:not(.header) { background-color: #eee; }
问题原因
当输入框内容为空时,空字符串调用indexOf()方法匹配任意字符串都会返回索引0,因此所有联系人条目都会被判定为匹配项,导致列表全量展示;同时原有CSS没有给联系人列表设置默认隐藏样式,页面初始加载时列表就处于可见状态。
修改方案
只需要修改两处代码即可实现预期效果:
- 修改CSS中
#myUL选择器的样式,添加默认隐藏规则 - 优化JS搜索逻辑,增加输入为空的判断分支,输入为空时直接隐藏整个列表,不执行匹配逻辑;有有效输入时再展示列表并过滤结果
修改后的CSS
仅需在#myUL的样式规则中新增display: none;:
#myUL { list-style-type: none; padding: 0; margin: 0; display: none; /* 默认隐藏联系人列表 */ }
修改后的JavaScript函数
function myFunction() { var input, filter, ul, li, a, i, txtValue; input = document.getElementById("myInput"); // 增加trim()处理,避免用户仅输入空格时触发全量展示 filter = input.value.trim().toUpperCase(); ul = document.getElementById("myUL"); li = ul.getElementsByTagName("li"); // 输入为空时隐藏列表,终止后续逻辑 if (!filter) { ul.style.display = "none"; return; } // 存在有效输入时,先展示列表容器 ul.style.display = "block"; // 遍历所有联系人条目匹配过滤 for (i = 0; i < li.length; i++) { a = li[i].getElementsByTagName("a")[0]; txtValue = a.textContent || a.innerText; if (txtValue.toUpperCase().indexOf(filter) > -1) { li[i].style.display = ""; } else { li[i].style.display = "none"; } } }
最终效果
- 页面初始加载、用户清空输入框内容时,联系人列表自动隐藏
- 用户输入有效字符后,列表自动展示,仅显示与输入内容匹配的联系人
- 输入过程中实时过滤结果,完全符合预期需求
内容的提问来源于stack exchange,提问作者confusedcoder
相关产品推荐
相关产品推荐

