一个两百多条的产品列表页,靠 Ctrl+F 只能跳转不能过滤,用户想看的型号还是埋在中间。加个搜索框其实十几行代码,不用引框架。

结构只有三样东西

一个输入框,一个装列表的 ul,每条数据放一个 li。输入框用 type='search',浏览器自带清除按钮,手机键盘的确认键也会变成搜索。记得配 aria-label 或 label,读屏软件才知道它是干什么的。

<input type='search' id='q' placeholder='输入型号' aria-label='搜索产品'>

过滤逻辑

监听 input 事件而不是 keyup,粘贴和输入法上屏都能触发。取值后 trim 去空格、toLowerCase 统一小写,再遍历 li 用 textContent 匹配,命中就清掉 display,没命中设成 none。输入为空时要把所有项还原,否则删完关键词列表就空了。

const q = document.getElementById('q');
items.forEach(li => li.style.display = li.textContent.includes(kw) ? '' : 'none')

上面这行是核心,kw 是处理过的关键词,items 用 querySelectorAll('#list li') 取一次存起来,别在事件里反复查询 DOM。

几个实际问题

中文不需要分词,includes 够用;想要拼音首字母搜索就得引入 pinyin 库,成本立刻上去。数据超过两三千条,逐条改 DOM 会卡,改成数组存数据、只渲染命中的前五十条。搜索框别把 outline 设成 none,键盘 Tab 聚焦时看不见焦点框,是无障碍里最常见的问题。

样式和手机上的细节

输入框宽度给 100%,再加 box-sizing: border-box,不然内边距会把容器撑破。字号别小于 16px,iOS 上聚焦时会自动放大整个页面,看着像页面坏了。筛选结果为空时补一句提示,比一片空白友好得多。

静态页用这套就够,别为了一个输入框上 React。等要分页、要关键词高亮、要记搜索历史了,再换方案也不迟。