layui原生select不支持关键词高亮,因lay-search仅控制dd显隐而不修改文本;需手动在dd.innerhtml中用正则替换关键词并包裹标签,注意转义、时机及dom层级。
layui 原生 select 组件不支持关键词高亮,必须手动干预渲染逻辑——不是加个属性就能解决的事。
为什么原生 lay-search 不高亮?
因为 lay-search 只控制选项的显隐(调用 notOption 函数遍历 dd 并设 display),它从不修改 DOM 文本内容,更不会插入 <em></em> 或其他标签包裹关键词。高亮是纯前端渲染层行为,Layui 把这部分完全交给你自己处理。
最简可行方案:改写 dd 的 innerHTML
在搜索匹配逻辑执行后、DOM 更新前,对每个匹配项的文本做一次关键词替换。关键点在于:不能直接操作原始 option,而是操作 Layui 渲染出的 dd 元素。
- 监听
input事件后,先拿到当前输入值val - 遍历所有
$('#inputSelect dd')(注意:不是select option) - 对每个
dd的textContent执行replace,用正则包裹关键词:new RegExp(val, 'gi') - 把替换结果赋给
dd.innerHTML,但要确保只替换文本部分,避免破坏onclick等属性
示例片段:
function highlightText(dd, val) {
if (!val) return;
const text = dd.textContent || dd.innerText;
const escapedVal = val.replace(/[.*+?^${}()|[]\]/g, '\$&'); // 转义正则特殊字符
const regex = new RegExp(`(${escapedVal})`, 'gi');
dd.innerHTML = text.replace(regex, '<em style="color:#01AAED">$1</em>');
}
使用 xm-select 时 filter + templet 组合实现高亮
如果你用的是第三方增强插件 xm-select,它提供 templet 配置项,可安全注入 HTML。这时高亮逻辑更可控,且不依赖 DOM 操作时机。
-
filter仍负责是否显示该选项(返回布尔值) -
templet负责怎么显示,接收item和val,可自由拼接带<em></em>的字符串 - 注意:必须对
val做正则转义,否则用户输*或(会报错 - 别忘了在 CSS 中定义
em样式,否则高亮无视觉反馈
templet 示例:
templet: function(item, val) {
if (!val) return item.name;
const escaped = val.replace(/[.*+?^${}()|[]\]/g, '\$&');
const html = item.name.replace(new RegExp(`(${escaped})`, 'gi'), '<em>$1</em>');
return html;
}
容易忽略的细节和坑
高亮不是“加个 <em></em>”就完事,几个真实项目里反复踩过的点:
- 中文多音字、拼音缩写(如“GZ”匹配“广州”)需要额外做拼音转换,
lay-search原生不支持 - 连续多次输入触发多次高亮,若没清除旧
<em></em>,会导致嵌套标签,最终显示为文字乱码 - 移动端软键盘切换输入法时,
input事件可能不触发,需同时监听compositionend - 如果选项含 HTML 实体(如
),直接innerHTML = ...可能被二次转义,建议统一用textContent提取再处理
真正难的从来不是“怎么加高亮”,而是“怎么让高亮稳定出现在正确时机、不破坏已有交互、不引入新 bug”。动手前,先用开发者工具确认你操作的是哪一层 DOM 节点。











