您现在的位置是:网站首页> 编程资料编程资料
HTML高亮关键字的实现代码HTML高亮关键字的完美解决方案
2023-10-16
373人已围观
简介 这篇文章主要介绍了HTML高亮关键字的实现代码的相关资料,本以为一个 innerHTML replace 就能实现的简单操作,却遇到了许多的问题。本文就记录这些问题和最终的完美解决办法, 希望能对有同样遭遇的小伙伴有所帮助
本以为一个 innerHTML replace 就能实现的简单操作,却遇到了许多的问题。本文就记录这些问题和最终的完美解决办法, 希望能对有同样遭遇的小伙伴有所帮助。只对结果感兴趣的,忽略过程,直接跳过看结果吧~
常用做法:正则替换
思路:要想高亮元素,那么需要将关键字提取出来用标签包裹,然后对标签进行样式调整。使用 innerHTML,或 outHTML, 而不能使用 innerText,outText。
const regex = new RegExp(keyword,"g") element.innerHTML = element.innerHTML.replace(regex,""+keyword+"") element.classList.add("highlight") 这样做存在的隐患有如下:
- keyword 如果是 ()\ 等正则对象的关键字将会构建正则对象失败。(可以通过转义解决)
- keyword 如果是一些 HTML 标签如 div 将会对 innerHTML 进行错误的替换
- keyword 如果和一些DOM属性名、值相同,也会导致异常替换。如下当 keyword 为 test 时,会将 class 名也错误的替换掉:
test
关键字父节点 element 通过 class 来进行背景染色处理,对原始DOM有一定程度污染,可能对 element 再次定位造成影响。(作为插件希望尽可能少改变原始DOM)
正则优化一:仅处理位于标签内的元素
var formatKeyword = text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') // 转义处理keyword包含的特殊字符,如 /. var finder = new RegExp(">.*?"++".*?<") // 提取位于标签内的文本,避免误操作 class、id 等 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++ } } }最后,留个彩蛋,以上方法也是存在一个小 bug 的,有兴趣可以去发现一下。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
相关内容
- 前端canvas动画如何转成mp4视频的方法HTML5 Canvas 破碎重组的视频特效的示例代码canvas像素点操作之视频绿幕抠图video结合canvas实现视频在线截图功能canvas绘制视频封面的方法详解基于canvas的视频遮罩插件canvas与html5实现视频截图功能示例Canvas获取视频第一帧缩略图的实现
- Html5 实现微信分享及自定义内容的流程HTML5播放实现rtmp流直播html5用video标签流式加载的实现基于 HTML5 WebGL 实现的医疗物流系统HTML5 canvas 瀑布流文字效果的示例代码HTML5移动端手机网站开发流程HTML5实现的图片无限加载的瀑布流效果另带边框圆角阴影HTML5梦幻之旅——炫丽的流星雨效果实现过程HTML5 离线应用之打造零请求、无流量网站的解决方法Html5之webcoekt播放JPEG图片流
- 详解利用canvas实现环形进度条的方法canvas实现圆形进度条动画的示例代码HTML5 Canvas 实现圆形进度条并显示数字百分比效果示例HTML5 Canvas玩转酷炫大波浪进度图效果实例(附demo)
- HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)html5实现点击弹出图片功能html5 录制mp3音频支持采样率和比特率设置html5表单的required属性使用html5调用摄像头实例代码HTML5页面音频自动播放的实现方式Html5大屏数据可视化开发的实现html实现弹窗的实例HTML5来实现本地文件读取和写入的实现方法HTML 罗盘式时钟的实现HTML5简单实现添加背景音乐的几种方法
- 利用canvas实现图片下载功能来实现浏览器兼容问题canvas 下载二维码和图片加水印的方法html5使用canvas实现图片下载功能的示例代码
- Canvas 文字碰撞检测并抽稀的方法Html5 Canvas动画基础碰撞检测的实现
- 叉叉助手ios安装教程 叉叉游戏助手ios怎么用 _手机游戏_游戏攻略_
- 时空猎人 猫女装备要怎么选择 猫女的装备心得_手机游戏_游戏攻略_
- 我是火影 影忍怎么合成 影忍合成注意事项_手机游戏_游戏攻略_
- 我是火影 怎么获得试炼奖励 真人安排组合推荐_手机游戏_游戏攻略_
