需求
用户输入搜索关键字时,需要将匹配的文本高亮显示。
效果演示
核心要素
Highlight 对象
- 通过
new Highlight()
创建,用于存储所有需要高亮的文本范围(Range)。
highlight.add(range)
方法添加范围。
highlight.clear()
方法清空高亮。
CSS.highlights.set()
- 将高亮对象注册到命名样式,如
'search-highlight'
。
- 对应的 CSS 通过
::highlight(search-highlight)
生效。
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拓展插件,很好玩哦,感兴趣的话,给我的公众号回复牛马
即可免费获取。
我的微信公众号: 梨的前端小屋