
本文介绍在实时搜索建议列表中,根据用户输入动态加粗匹配字符的实现方法,保持原有字符顺序不变,支持大小写不敏感匹配,并通过正则替换与 dom 操作精准渲染高亮效果。
本文介绍在实时搜索建议列表中,根据用户输入动态加粗匹配字符的实现方法,保持原有字符顺序不变,支持大小写不敏感匹配,并通过正则替换与 dom 操作精准渲染高亮效果。
在构建预测式搜索(如水果名称搜索)时,仅显示匹配项还不够——良好的用户体验要求视觉上突出用户输入的关键字。关键在于:不能简单地对整个 <li> 设置 font-weight: bold,而需仅加粗字符串中实际匹配的部分,且严格保留原始大小写与字符位置。
核心思路是:利用正则表达式(RegExp)进行不区分大小写的全局匹配,再通过 String.prototype.replace() 将匹配到的子串包裹进带样式的 <span></span> 标签。注意使用 $& 作为替换占位符,它代表正则匹配到的原始内容(含原始大小写),从而完美保序、保形。
以下是优化后的完整实现:
const fruit = ["Apple", "Banana", "Grape"];
function search(str) {
if (!str.trim()) return [];
return fruit.filter(el => el.toLowerCase().includes(str.toLowerCase()));
}
function searchHandler() {
const input = document.getElementById('fruit');
const ul = document.querySelector('.suggestions > ul');
ul.innerHTML = ''; // 清空旧结果(比 textContent 更安全,因需插入 HTML)
const results = search(input.value);
const regex = new RegExp(input.value, 'gi'); // 'g' 支持多次匹配,'i' 忽略大小写
results.forEach(item => {
const li = document.createElement('li');
// 关键:用 replace + $& 精准包裹匹配部分,其余文本原样保留
li.innerHTML = item.replace(regex, '<span class="has-suggestions">$&</span>');
ul.appendChild(li);
});
}对应 HTML 需绑定事件(推荐 oninput 实现即时响应):
<div class="search-container">
<input
type="text"
name="fruit"
id="fruit"
placeholder="Search fruit ?"
oninput="searchHandler()"
/>
<div class="suggestions">
<ul></ul>
</div>
</div>CSS 样式保持简洁有效:
.has-suggestions {
font-weight: bold;
/* 可选增强:添加背景色或颜色提升可读性 */
/* background-color: #ffeb3b; */
/* color: #212121; */
}⚠️ 注意事项:
- 使用
innerHTML替代textContent是必需的,因为我们要注入 HTML 标签;但务必确保input.value不含恶意脚本(本例为纯字母搜索,风险低;若涉及用户可控内容,需做 HTML 转义)。 - 正则标志
'gi'中的'g'很重要:避免只高亮首个匹配项(例如搜索"e"在"Apple"中应高亮两个e)。 - 若输入为空字符串,
new RegExp('', 'gi')会匹配任意位置,导致全字加粗甚至无限循环,因此search()函数开头增加了if (!str.trim()) return [];防御。 - 该方案天然支持多字匹配(如输入
"app"匹配"Apple"中的"app",而非仅单字符)。
此方法轻量、可靠、语义清晰,是前端搜索高亮的经典实践。

















