如何利用 JavaScript 实现一个支持自动完成的搜索输入框?

答案:通过原生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;

    // 过滤出匹配项 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 获取远程数据,结构保持不变。不复杂但容易忽略细节,比如清空条件和焦点管理。