*新闻详情页*/>
本认为1个 innerHTML replace 就可以完成的简易实际操作,却遇到了很多的难题。本文就纪录这些难题和最后的完善处理方法, 期待能对有一样遭受的小伙子伴随所协助。只对結果感兴趣爱好的,忽视全过程,立即绕过看結果吧~
常见做法:正则表达式更换
思路:要想高亮度元素,那末必须将重要字提取下来用标识包裹,随后对标识开展款式调剂。应用 innerHTML,或 outHTML, 而不可以应用 innerText,outText。
const regex = new RegExp(keyword,"g") element.innerHTML = element.innerHTML.replace(regex,"<b class="a">"+keyword+"</b>") element.classList.add("highlight")
这样做存在的隐得了以下:
<div id="parent"> <div class="test">test</div> </div>
重要字父连接点 element 根据 class 来开展情况染色解决,对初始DOM有1定水平污染,将会对 element 再度精准定位导致危害。(做为软件期待尽量少更改初始DOM)
正则表达式提升1:仅解决坐落于标识内的元素
var formatKeyword = text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') // 转义解决keyword包括的独特标识符,如 /. var finder = new RegExp(">.*?"++".*?<") // 提取坐落于标识内的文字,防止误实际操作 class、id 等 element.innerHTML = element.innerHTML.replace(finder,function(matched){ return matched.replace(text,"<br>"+text+</br>) })// 对提取的标识内文字开展重要字更换
以能处理大多数数难题,但依然存在的难题是,要是标识特性存在相近 < 标记,可能摆脱配对标准致使正则表达式提取內容不正确, HTML5 dataset 能够自定随意內容,故这些独特标识符是没法防止的。
<div dataset="p>d">更换</div>
正则表达式提升2:消除将会危害的标识
<div id="keyword">keyword</div> =》将闭合标识用自变量更换 [replaced1]keyword[replaced2]//闭合标识内 id="keyword" 不容易被解决 =》 [replaced1]<b>keyword</b>[replaced2] =》将暂存自变量 replaced 更换为本来标识 <div id="keyword"><b>keyword</b></div>
这类思路及源代码从这里来, 但存在难题是:
总而言之在历经了N多尝试以后,根据正则表达式都没能合理的解决各种各样状况。随后换了个思路,堵塞过标识符串的方法,根据连接点解决。element.childNodes 能够最合理的清除标识内的影响信息内容。
[完善处理计划方案]根据 DOM 连接点解决
<div id="parent"> keyword 1 <span id="child"> keyword 2 </span> </div>
根据 parent.childNodes 获得全部子连接点。child 连接点能够根据 innerText.replce(keyword,result) 的方法更换获得要想的高亮度实际效果,以下: <span id="child"><b>keyword</b> 2</span> (递归解决:当child连接点不含子连接点时开展replace实际操作)。
可是 keyword 1 是属于文字连接点,只能改动文字內容,没法提升 HTML,更没法独立操纵其款式。而文字连接点也不可以变换为一般连接点,这也是最苦恼的事儿。
最终~,本文的关键来了,由于这个作用,让我第1次用心触碰到了文字连接点这个物品。从这里发现了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); // 激光切割成前 重要词 后3个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++ } } }
最终,留个彩蛋,以上方式也是存在1个小 bug 的,有兴趣爱好能够去发现1下。
以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。
Copyright © 2002-2020 快速建站_网站建设系统_免费网页建站_网站免费建设_建站系统 版权所有 (网站地图) 粤ICP备10235580号