本文发布于个人网站:https://wintc.top/article/59,转载请注明
很久之前(好像刚好是一年前)写过一个Vue组件,匹配文本内容中的关键词高亮,类似浏览器ctrl+f搜索结果。实现方案是,将文本字符串中的关键字搜索出来,然后使用特殊的标签(比如font标签)包裹关键词替换匹配内容,最后得到一个HTML字符串,渲染该字符串并在font标签上使用CSS样式即可实现高亮的效果。
当时的实现过于简单,没有支持接收HTML字符串作为内容进行关键词匹配。这两天有同学问到,就又思考了这个问题,发现并不是那么麻烦,写了几行代码解决了一下。
一、匹配关键字:HTML字符串与文本字符串对比
1. 纯文本字符串的处理
对于纯文本字符串,如:“江畔何人初见月?江月何年初照人? ”,假如我们想匹配“江月”这个关键字,则匹配结果可处理为:
江畔何人初见月?<font style="background: #ff9632">江月</font>何年初照人?
这样“江月”两个字被font标签包裹,在font标签上应用特殊的背景样式以达到关键字高亮的效果。
2. 对HTML字符串的处理
对于上述例子,如果内容字符串是一个HTML文本:
江畔何人初见<b>月</b>?江<b>月</b>何年初照人?
对于同样的关键词“江月”,怎样处理它呢?因为关键词中的字在不同的标签内,所以只能分别用font标签进行替换:
江畔何人初见<b>月</b>?<font style="background: #ff9632">江</font><b><font style="background: #ff9632">月</font></b>何年初照人?
这是比较简单的情况,实际情况下关键字则可能跨多级、多层标签。
二、跨标签匹配关键词
跨标签解析关键词,其实就是对于匹配到的关键词,提取出各标签中对应的子片段,然后用font之类的标签包裹,再将高亮样式用于font标签即可。
对于整个HTML内容而言,渲染出来的文本由各类标签内的文本节点组成。因为关键词匹配的内容会跨标签,所以需要将各文本节点有序取出,并将节点内容拼接起来进行匹配。拼接时记下节点文本在拼接串中的起止位置,以便关键词匹配到拼接串的某位置时截取文本片段并使用font标签包裹。