最近做项目遇到这样的一个功能:在网页中高亮关键字。

本以为一个 innerHTML replace 就能实现的简单操作,却遇到了许多的问题。本文就记录这些问题和最终的完美解决办法, 希望能对有同样遭遇的小伙伴有所帮助。只对结果感兴趣的,忽略过程,直接跳过看结果吧~

常用做法:正则替换

思路:要想高亮元素,那么需要将关键字提取出来用标签包裹,然后对标签进行样式调整。使用 innerHTML,或 outHTML, 而不能使用 innerText,outText。

const regex = new RegExp(keyword,"g")

element.innerHTML = element.innerHTML.replace(regex,""+keyword+"")

element.classList.add("highlight")

这样做存在的隐患有如下:

()

div

test

关键字父节点 element 通过 class 来进行背景染色处理,对原始DOM有一定程度污染,可能对 element 再次定位造成影响。(作为插件希望尽可能少改变原始DOM)

正则优化一:仅处理位于标签内的元素

var formatKeyword = text.replace(/[-/\^$*+?.()|[]{}]/g, "\$&") // 转义处理keyword包含的特殊字符,如 /.

var finder = new RegExp(">.*?"++".*?

element.innerHTML = element.innerHTML.replace(finder,function(matched){

return matched.replace(text,"
"+text+)

})// 对提取的标签内文本进行关键字替换

以能解决大多数问题,但依旧存在的问题是,只要标签属性存在类似 < 符号,将会打破匹配规则导致正则提取内容错误, HTML5 dataset 可以自定义任意内容,故这些特殊字符是无法避免的。

替换

正则优化二:清除可能影响的标签

keyword

=》将闭合标签用变量替换

[replaced1]keyword[replaced2]//闭合标签内 id="keyword" 不会被处理

=》

[replaced1]keyword[replaced2]

=》将暂存变量 replaced 替换为原先标签

keyword

这种思路及源码从这里来, 但存在问题是:

如果 [replaced1] 包含 keyword, 那么替换时将发生异常

最重要的,当标签值中包含 <> 符号时,此方法也不能正确的提取标签

总之在经过了N多尝试之后,通过正则都没能有效的处理各种情况。然后换了个思路,不通过字符串的方式,通过节点处理。element.childNodes 可以最有效的清理标签内的干扰信息。

[完美解决方案]通过 DOM 节点处理

keyword 1

keyword 2

通过 parent.childNodes 得到所有子节点。child 节点可以通过 innerText.replce(keyword,result)的方式替换得到想要的高亮效果,如下: keyword 2(递归处理:当child节点不含子节点时进行replace操作)。

但是 keyword 1 是属于文本节点,只能修改文本内容,无法增加 HTML,更无法单独控制其样式。而文本节点也不能转换为普通节点,这也是最苦恼的事情。

最后~,本文的重点来了,因为这个功能,让我第一次认真接触到了文本节点这个东西。从这里发现了Text,使用切割文本节点并替换的方式实现高亮。

源码以及还原高亮见源码

const reg = new RegExp(keyword.replace(/[-/\^$*+?.()|[]{}]/g, "\$&"))

highlight = function (node,reg){

if (node.nodeType == 3) { //只处理文本节点

const match = node.data.match(new RegExp(reg));

if (match) {

const highlightEl = document.createElement("b");

highlightEl.dataset.highlight="y"

const wordNode = node.splitText(match.index)

wordNode.splitText(match[0].length); // 切割成前 关键词 后三个Text 节点

const wordNew = document.createTextNode(wordNode.data);

highlightEl.appendChild(wordNew);//highlight 节点构建成功

wordNode.parentNode.replaceChild(highlightEl, wordNode);// 替换该文本节点

}

} else if (node.nodeType == 1 && node.dataset.highlight!="y"

) {

for (var i = 0; i < node.childNodes.length; i++) {

highlight(node.childNodes[i], reg);

i++

}

}

}

总结

以上所述是小编给大家介绍的HTML高亮关键字的完美解决方案,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网页设计网站的支持!

html页面 关键字高亮,HTML高亮关键字的完美解决方案相关推荐

  1. 高亮word特定关键字(python)

    高亮word特定关键字(python) 第一次写博客,主要是记录一些日常写下的代码,算是记录,也为了自己之后便于查找. 今天主要是写一个利用python对word的内容进行操作,具体是指高亮特定的文字 ...

  2. 微信小程序input输入框关键字自动联想及关键字高亮

    找了好多博客都没有找到关于小程序,模糊查询,自动联想,和关键字高亮显示的文章,没办法,自己造吧. 本文采用的是动态联想,即在input框中输入关键字后,将关键字作为条件去数据库查询,然后将所有查询结果 ...

  3. 如何在IE浏览器里面定位到关键字的位置(页面代码)和这个关键字位置模块的请求

    1 问题 比如用IE浏览器,打开一个页面,如何定位到关键字的具体位置,以及这个位置请求是什么?可能这个请求不是主页面的请求,因为我们知道页面html里面可以嵌套很多Frame(框架),把页面分割成很多 ...

  4. 如何利用Google关键字工具获取网站关键字

    Google Adwords关键字工具通过基于搜索的关键字建议,可以按字词.词组.网站或类别获取关键字提示.是站长朋友们,尤其是做英文Google Adsense的英文站站长在网站关键字选择上必不可少 ...

  5. PHP访问关键字,php数据访问之查询关键字,php数据关键字_PHP教程

    php数据访问之查询关键字,php数据关键字 本文实例为大家分享了php查询操作的实现代码,供大家参考,具体内容如下 一.一个关键字查询 主页面: 汽车查询页面 汽车查询页面请输入查询内容: 代号 汽 ...

  6. C语言register关键字——最快的关键字

    C语言register关键字-最快的关键字 (2012-08-24 14:09:24) 转载▼ 标签: 杂谈 分类: C/C    register:这个关键字请求编译器尽可能的将变量存在CPU内部寄 ...

  7. 根据作用C语言关键字分为,C语言 关键字

    关键字就是已被C语言本身使用,不能作其它用途使用的字.例如关键字不能用作变量名.函数名等 由ANSI标准定义的C语言关键字共32个. 根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两 ...

  8. Java关键字(53个关键字)

    Java关键字(53个关键字) abstract  default  goto*  null  switch  boolean  do  if  package  nchronzed  break  ...

  9. python可变参数和关键字参数位置_python笔记——函数的参数(位置参数、默认参数、可变参数、关键字参数、命名关键字参数、参数组合)...

    定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解 ...

  10. java的关键字和保留字_Java关键字和保留字及其含义

    1.java的关键字(keyword)有多少个? 51+2个保留字=53个关键字(java的关键字都是小写的!!) 2.java的保留字(reserve word)有多少个?问题:分别是什么? 2个保 ...

最新文章

  1. Github无法加载或不显示图片问题
  2. vue.js中请求数据v-for循环使用数据
  3. (八)OpenStack---M版---双节点搭建---Cinder安装和配置
  4. wxHtml 示例:关于对话框测试
  5. 06_clickhouse、表和列的TTL规则与实践、表和列的TTL、列级TTL、表级TTL、列级TTL示例、表级TTL示例
  6. supervisor进程管理工具
  7. IDE-Ecplise-代码注释 模版 编码规范 配色
  8. [蓝桥杯2019初赛]矩形切割-找规律
  9. python binascii array('c')_详解Python中的array数组模块相关使用
  10. viewDidLoad等相关函数调用
  11. MATLAB学习——矩阵
  12. 设置ubuntu默认python3设置
  13. 开发一个Swing功能时的一点总结
  14. ipython和anaconda区别_anaconda和python区别
  15. CSS 框的外观 outline属性
  16. Spring-ConfigurationClassPostProcessor类
  17. 数据结构与算法python—12.二叉搜索树及python实现与leetcode总结
  18. cargo 使用国内源镜像,引用 substrate 的 Contracts Pallet Crate 编译错误
  19. 将高德坐标拾取工具放入Element UI 对话框
  20. 从知名外企到创业公司做CTO是一种怎样的体验?

热门文章

  1. 《树莓派4B家庭服务器搭建指南》第六期:将RSSHub私有化部署到树莓派,并通过《嘎!RSS》订阅自己的信息流...
  2. Excel成神之道-002-数据分组汇总
  3. python分组统计excel数据_在python中对数据进行分组并与excel进行比较
  4. 【刘晓燕长难句分析】1.简单句
  5. city机器人 东京diver_东京一日游路线推荐
  6. dpbs和pbs的区别_PBS与TBS区别
  7. Google搜索引擎设置百度搜索
  8. 常见量化投资误区合集,量化交易新手脱坑指南 | 邢不行
  9. matlab 怎么打开.p文件,matlab p文件肿么打开 或者 运行
  10. 做word计算机海报图片,使用word制作宣传海报