前端轻松实现搜索文本高亮


需求

用户输入搜索关键字时,需要将匹配的文本高亮显示。

效果演示

核心要素

  1. Highlight 对象

    • 通过 new Highlight() 创建,用于存储所有需要高亮的文本范围(Range)。
    • highlight.add(range) 方法添加范围。
    • highlight.clear() 方法清空高亮。
  2. CSS.highlights.set()

    • 将高亮对象注册到命名样式,如 'search-highlight'
    • 对应的 CSS 通过 ::highlight(search-highlight) 生效。
  3. Range 操作

    • 使用 range.setStart(node, offset)range.setEnd(node, offset) 定义文本范围。
    • textRef.value.firstChild 指向文本节点( div 元素中只能有文本)。

代码实例

html

1
2
<input class="input" v-model="searchText" @input="handleHighlight"  placeholder="请输入..."/>
<p ref="textRef" >微信公众号:梨的前端小屋</p>

css

1
2
3
4
5
::highlight(search-highlight) {
background-color: yellow;
color: black;
text-decoration: underline;
}

js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<script setup>
import { ref, onMounted } from 'vue';
const textRef = ref(null);

const searchText = ref('');
const highlight = new Highlight(); // 创建高亮对象

onMounted(() => {
CSS.highlights.set('search-highlight', highlight); // 注册高亮
});

// 应用高亮
const handleHighlight = () => {
highlight.clear(); // 清空旧高亮
if (!searchText.value || !textRef.value) return;
const text = textRef.value.textContent;
const regex = new RegExp(escapeRegExp(searchText.value), 'gi'); // 匹配所有需要转义的特殊字符
let match;

while ((match = regex.exec(text)) !== null) {
const range = new Range();
range.setStart(textRef.value.firstChild, match.index);
range.setEnd(textRef.value.firstChild, match.index + match[0].length);
highlight.add(range); // 添加新范围
}
};

// 转义正则特殊字符
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
</script>

哦对了,我最近开发了一个叫牛马工作器的chrome拓展插件,很好玩哦,感兴趣的话,给我的公众号回复牛马即可免费获取。

我的微信公众号: 梨的前端小屋


文章作者: 梨啊梨
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 梨啊梨 !
  目录