目的:在全网页中将关键词高亮展示,以实现ctrl+f 查找的类似效果。
实现思路:
通过遍历dom节点,得到所有的text节点,然后将节点的内容进行高亮展示。
实现过程:
一、首先需要得到所有的文本节点,
方法一:使用createTreeWalker方法获取到所有的文本节点。代码如下:
function textNodesUnder(el){
var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false);
while(n=walk.nextNode()) a.push(n);
return a;
}
方法二:递归得到所有的文本节点,代码如下:
function textNodesUnder(node){
var all = [];
for (node=node.firstChild;node;node=node.nextSibling){
if (node.nodeType==3) all.push(node);
else all = all.concat(textNodesUnder(node));
}
return all;
}
注:这里之所以要得到节点并且存到数组中,是因为如果一边遍历一边修改替换节点,会对节点造成干扰。(踩坑得出的结论)
在得到文本节点之后,再对文本节点进行操作。
如何高亮关键词
在获取到所有的节点之后,我们需要替换指定位置的关键词为高亮的节点,这里可以使用replaceALL将匹配的关键词替换为<font color="XXX">关键词</font>
的标签,然后新建一个节点(为了尽量减少影响此处选择span
),将节点的innerHTML设置成替换之后的内容。最后再用新节点替换之前的节点,最后实现需要的效果。(实际上是在原来的节点里包了一个span标签,然后通过其innerHTML来实现)代码如下:
const arr = textNodesUnder(document.body)
arr.forEach(item=>{
const newNode = document.createElement('span')
newNode.innerHTML = item.data.replaceAll('匹配关键词','<font color="自定义颜色">替换关键词</font>')
item.replaceWith(newNode)
})