相信大家在网页上 使用ctrl+f 搜索的某些内容的时候,匹配到的内容会语法高亮显示,有提示作用,如下图:
那么这种效果是如何实现的呢?主要有以下几个步骤:
- 使用Range对象,range表示一个包含节点与文本节点的一部分的文档片段
- 为创建范围创建highlight对象,并进行注册
- 使用::highlight 伪元素定义高亮样
以上是主要步骤,具体需要进行文本筛选,处理数据,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
::highlight(my_higtlight) {
color: rgb(38, 49, 59);
background-color: aquamarine;
}
</style>
<title>搜索语法高亮显示</title>
</head>
<body>
<div>
<!-- <p id="queryBOx">Search within text <input id="query" type="text" /></p> -->
Search within text <input id="query" type="text" />
<article>
<p>
Maxime debitis hic, delectus perspiciatis laborum molestiae labore,
deleniti, quam consequatur iure veniam alias voluptas nisi quo. Dolorem
eaque alias, quo vel quas repudiandae architecto deserunt quidem, sapiente
laudantium nulla.
</p>
<p>
Maiores odit molestias, necessitatibus doloremque dolor illum reprehenderit
provident nostrum laboriosam iste, tempore perferendis! Ab porro neque esse
voluptas libero necessitatibus fugiat, ex, minus atque deserunt veniam
molestiae tempora? Vitae.
</p>
<p>
Dolorum facilis voluptate eaque eius similique ducimus dignissimos assumenda
quos architecto. Doloremque deleniti non exercitationem rerum quam alias
harum, nisi obcaecati corporis temporibus vero sapiente voluptatum est
quibusdam id ipsa.
</p>
</article>
</div>
</body>
</html>
<script>
let query = document.querySelector('#query')
let article = document.querySelector('article')
let treeWalker = document.createTreeWalker(article, NodeFilter.SHOW_TEXT)
let nodeList = []
let currentNode = treeWalker.nextNode()
while (currentNode) {
nodeList.push(currentNode)
currentNode = treeWalker.nextNode()
}
query.addEventListener('input', () => {
if (!CSS.highlights) {
alert('不支持语法高亮')
}
const str = query.value.trim().toLowerCase();
CSS.highlights.clear();
if (!str) {
return
}
const ranges = nodeList.map(e => {
return { e, textContent: e.textContent.toLowerCase() }
}).map(({ e, textContent }) => {
const list = []
let setStartIndex = 0
while (setStartIndex < textContent.length) {
let index = textContent.indexOf(str, setStartIndex)
if (index === -1) break
list.push(index)
setStartIndex = index + str.length
}
return list.map(i => {
let range = new Range()
range.setStart(e, i)
range.setEnd(e, i + str.length)
return range
})
})
const searchHighLight = new Highlight(...ranges.flat())
CSS.highlights.set('my_higtlight', searchHighLight)
})
</script>
代码运行效果: