答案:通过原生JavaScript监听输入事件,过滤数据源生成匹配建议并动态渲染下拉列表,支持鼠标点击与键盘上下键导航选择,结合防抖优化性能,实现完整的自动完成功能。

要实现一个支持自动完成的搜索输入框,核心思路是监听用户输入,动态匹配建议列表,并将结果展示在下拉菜单中供选择。整个过程不依赖第三方库,使用原生 JavaScript 即可完成。
1. 基本 HTML 结构
先搭建输入框和建议列表的结构:
2. 定义数据源与输入监听
准备一组用于匹配的关键词,比如城市名或商品名称。然后监听输入框的 input 事件:
const searchInput = document.getElementById('searchInput');
const suggestionsList = document.getElementById('suggestions');
const data = ['JavaScript', 'Java', 'Python', 'TypeScript', 'Ruby', 'Go', 'PHP'];
searchInput.addEventListener('input', function () {
const value = this.value.trim().toLowerCase();
suggestionsList.innerHTML = ''; // 清空上一次结果
if (!value) return;
立即学习“Java免费学习笔记(深入)”;
// 过滤出匹配项
const matches = data.filter(item =>
item.toLowerCase().includes(value)
);
// 插入建议项
matches.forEach(match => {
const li = document.createElement('li');
li.textContent = match;
li.onclick = function () {
searchInput.value = match;
suggestionsList.innerHTML = '';
};
suggestionsList.appendChild(li);
});
});
3. 添加样式与交互优化
为了让体验更自然,添加一些基础样式,并支持键盘上下选择:
.suggestions-list {
list-style: none;
padding: 0;
margin: 0;
border: 1px solid #ccc;
max-height: 150px;
overflow-y: auto;
display: none;
}
.suggestions-list li {
padding: 8px 12px;
cursor: pointer;
}
.suggestions-list li:hover,
.suggestions-list li.selected {
background-color: #f0f0f0;
}
当有建议时显示列表:
if (matches.length > 0) {
suggestionsList.style.display = 'block';
} else {
suggestionsList.style.display = 'none';
}
支持键盘导航(上下键和回车):
let selectedIndex = -1;searchInput.addEventListener('keydown', function (e) { const items = suggestionsList.getElementsByTagName('li');
if (e.key === 'ArrowDown') { e.preventDefault(); selectedIndex = (selectedIndex + 1) % items.length; updateSelection(items); } else if (e.key === 'ArrowUp') { e.preventDefault(); selectedIndex = (selectedIndex - 1 + items.length) % items.length; updateSelection(items); } else if (e.key === 'Enter' && selectedIndex > -1) { e.preventDefault(); searchInput.value = items[selectedIndex].textContent; suggestionsList.innerHTML = ''; selectedIndex = -1; } });
function updateSelection(items) { Array.from(items).forEach((item, i) => { item.classList.toggle('selected', i === selectedIndex); }); }
4. 防抖处理提升性能
如果数据量大或需请求远程接口,建议加入防抖,避免频繁触发匹配:
function debounce(func, delay) {
let timeoutId;
return function () {
const context = this;
const args = arguments;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(context, args), delay);
};
}
// 使用方式
searchInput.addEventListener('input', debounce(function () {
// 匹配逻辑
}, 300));
基本上就这些。通过监听输入、过滤数据、动态渲染和键盘支持,就能实现一个流畅的自动完成搜索框。可以根据需要接入 AJAX 获取远程数据,结构保持不变。不复杂但容易忽略细节,比如清空条件和焦点管理。










