目录方法1:使用纯正则替换1.重点代码:2.普通版完整函数(不带不可见字符&#情况):3.进阶版完整函数(word导入后或者有时候带了&#不可见字符转文字的情况下):4.decoders函数:5.锚点部分:6.锚点定位的使用:7.定位的主要代码在8.锚点完整代码:方法2:使用文本替换锚点后。使用range方法实现切换高亮。(防止数据太多。导致上下切换高亮卡顿)1.替换&#不可见生成的字符(例如?;等之类的)并替换掉标签。使所有关键词高亮。2.高亮的方法函数(默认第一个高亮):3.切换上一个和下一个(不卡顿)文章内容大致为:通过v-html渲染的页面。data中的某些值:关于方法2的知识点参考:http://t.csdn.cn/DT92m
方法1:使用纯正则替换
1.重点代码:
这边就是忽略标签直接匹配内容的部分,val为你搜索的内容文字
constreg=newRegExp(val,'g')this.detailLi.content=this.detailLi.content.replace(newRegExp('(?=\>).?(?=\<)','g'),function(str){constreg1=newRegExp('(?=>).','g')returnstr.replace(newRegExp('(>).','g'),function(str2){returnstr2.replace(reg1,function(str1){returnstr1.replace(reg,'<emstyle="background-color:yellow">'val'</em>')})})})2.普通版完整函数(不带不可见字符&#情况):
test就是你搜索按钮点击事件,val既搜索框的内容
test(val,x){this.pickNum=0if(val!==''){if(this.searData!==''){this.detailLi.content=this.searData}else{this.searData=this.detailLi.content}constreg=newRegExp(String(val),'g')//正则校验除了标签之外this.detailLi.content=this.detailLi.content.replace(newRegExp('(?=\>).?(?=\<)','g'),function(str){constreg1=newRegExp('(?=>).','g')returnstr.replace(newRegExp('(>).','g'),function(str2){returnstr2.replace(reg1,function(str1){//这边是判断乱码过滤(连接数据库成功!)正则校验除了这种的之外returnstr1.replace(newRegExp('^((?!(?=\&).?(?=\;)).)*$','g'),function(str0){returnstr0.replace(reg,`<spanid="test_idconese"style="background-color:#00a4ff">${val}</span>`)})})})})constvalue2=newRegExp('test_idconese','gi')this.allData=this.detailLi.content.match(value2)if(this.allData&&this.allData.length>0){this.allData.forEach((item,index)=>{this.detailLi.content=this.detailLi.content.replace('test_idconese',`test_${index}idconese`)})}this.detailLi.content=this.detailLi.content.replace('<spanid="test_0idconese"style="background-color:#00a4ff">','<spanid="test_0idconese"style="background-color:red">')}else{this.allData=[]}if(x){if(this.searData!==''){this.detailLi.content=this.searData}else{this.searData=this.detailLi.content}}},3.进阶版完整函数(word导入后或者有时候带了&#不可见字符转文字的情况下):
test为完整函数:里面的decoders事件写在后面。
test(val,x,keyWord){constthat=thisthis.pickNum=0if(val!==''){if(this.searData!==''){this.detailLi.content=this.searData}else{this.searData=this.detailLi.content}constreg=newRegExp(val,'g')//正则校验先乱码过滤(连接数据库成功!)正则校验除了这种的之外this.detailLi.content=this.detailLi.content.replace(newRegExp('(?=\>).?(?=\<)','g'),function(dades){if(dades.indexOf('&#')!==-1){returndades.replace(newRegExp('((?=\&).?)(?=\;)\;','g'),function(s){consttihuan=that.decoders(s)returndades.replace(dades,`${tihuan}`)})}else{returndades}})//正则校验除了标签之外this.detailLi.content=this.detailLi.content.replace(newRegExp('(?=\>).?(?=\<)','g'),function(str){constreg1=newRegExp('(?=>).','g')returnstr.replace(newRegExp('(>).','g'),function(str2){console.log(str2,'str22')returnstr2.replace(reg1,function(str1){console.log(str1.indexOf('&#'),str1,'str2')returnstr1.replace(reg,`<spanid="test_idconese"style="background-color:#00a4ff">${val}</span>`)//if(str1.indexOf('&#')!==-1){//returnstr1.replace(newRegExp('(?<=;)[^&](?=&)','g'),function(str0){//returnstr0.replace(reg,`<spanid="test_idconese"style="background-color:#00a4ff">${val}</span>`)//})//}else{////这边是判断乱码过滤(连接数据库成功!)正则校验除了这种的之外//returnstr1.replace(newRegExp('^((?!((?=\&).?)(?=\;)).)*$','g'),function(str0){//})//}})})})constvalue2=newRegExp('test_idconese','gi')this.allData=this.detailLi.content.match(value2)if(this.allData&&this.allData.length>0){this.allData.forEach((item,index)=>{this.detailLi.content=this.detailLi.content.replace('test_idconese',`test_${index}idconese`)})}this.detailLi.content=this.detailLi.content.replace('<spanid="test_0idconese"style="background-color:#00a4ff">','<spanid="test_0idconese"style="background-color:red">')this.$nextTick(function(){if(this.$el.querySelector('#test_0idconese')){this.$el.querySelector('#test_0idconese').scrollIntoView({behavior:'smooth',inline:'nearest',})}})}else{this.allData=[]}if(x){if(this.searData!==''){this.detailLi.content=this.searData}else{this.searData=this.detailLi.content}}},4.decoders函数:
&#特殊字符转文字的方法:
//&#编码转文字decoders(str){vartempArr=str.split(/\&#|\;/)console.log(str,tempArr,'tem')vartmpLength=tempArr.lengthvarstr=''for(vari=0;i<tmpLength;i){if(tempArr[i]!=''){str=String.fromCharCode(tempArr[i])}}returnstr},5.锚点部分:
1.先对所有匹配的内容添加统一相同的ID:
returnstr1.replace(reg,`<spanid="test_idconese"style="background-color:#00a4ff">${val}</span>`)
2.在通过match去获取有几个id为test_idconese的标签。并且遍历修改每个标签的ID添加index区别索引,用来后面锚点定位使用。
constvalue2=newRegExp('test_idconese','gi')this.allData=this.detailLi.content.match(value2)if(this.allData&&this.allData.length>0){this.allData.forEach((item,index)=>{this.detailLi.content=this.detailLi.content.replace('test_idconese',`test_${index}idconese`)})}6.锚点定位的使用:
这边的pickUp和pickDown就是ctrlF中的下一个关键词和上一个关键词,我这边是自己写了个按钮点击事件去执行它,num写着玩的。没有用。
7.定位的主要代码在
根据id去定位到锚点所在位置。
this.$el.querySelector('#test_0idconese').scrollIntoView({behavior:'smooth',inline:'nearest',})8.锚点完整代码:
pickUp(num){if(this.pickNum>0){this.pickNum=this.pickNum-1this.detailLi.content=this.detailLi.content.replace(`<spanid="test_${this.pickNum}idconese"style="background-color:#00a4ff">`,`<spanid="test_${this.pickNum}idconese"style="background-color:red">`)this.detailLi.content=this.detailLi.content.replace(`<spanid="test_${(this.pickNum1)}idconese"style="background-color:red">`,`<spanid="test_${(this.pickNum1)}idconese"style="background-color:#00a4ff">`)this.$el.querySelector(`#test_${this.pickNum}idconese`).scrollIntoView({behavior:'smooth',inline:'nearest',})}elseif(this.pickNum===0){this.$el.querySelector('#test_0idconese').scrollIntoView({behavior:'smooth',inline:'nearest',})}},pickDown(num){if(this.pickNum<this.allData.length-1){this.pickNum=this.pickNum1this.detailLi.content=this.detailLi.content.replace(`<spanid="test_${this.pickNum}idconese"style="background-color:#00a4ff">`,`<spanid="test_${this.pickNum}idconese"style="background-color:red">`)this.detailLi.content=this.detailLi.content.replace(`<spanid="test_${(this.pickNum-1)}idconese"style="background-color:red">`,`<spanid="test_${(this.pickNum-1)}idconese"style="background-color:#00a4ff">`)this.$el.querySelector(`#test_${this.pickNum}idconese`).scrollIntoView({behavior:'smooth',inline:'nearest',})}elseif(this.pickNum===0){this.$el.querySelector('#test_0idconese').scrollIntoView({behavior:'smooth',inline:'nearest',})}},方法2:使用文本替换锚点后。使用range方法实现切换高亮。(防止数据太多。导致上下切换高亮卡顿)
1.替换&#不可见生成的字符(例如?;等之类的)并替换掉标签。使所有关键词高亮。
test(val,x,keyWord){constthat=thisthis.pickNum=0if(val!==''){if(this.searData!==''){this.detailLi.content=this.searData}else{this.searData=this.detailLi.content}constreg=newRegExp(val,'g')//正则校验先乱码过滤(连接数据库成功!)正则校验除了这种的之外this.detailLi.content=this.detailLi.content.replace(newRegExp('(?=\>).?(?=\<)','g'),function(dades){if(dades.indexOf('&#')!==-1){returndades.replace(newRegExp('((?=\&).?)(?=\;)\;','g'),function(s){consttihuan=that.decoders(s)returndades.replace(dades,`${tihuan}`)})}else{returndades}})//正则校验除了标签之外this.detailLi.content=this.detailLi.content.replace(newRegExp('(?=\>).?(?=\<)','g'),function(str){constreg1=newRegExp('(?=>).','g')returnstr.replace(newRegExp('(>).','g'),function(str2){returnstr2.replace(reg1,function(str1){returnstr1.replace(reg,`<spanid="test_idconese"style="background-color:#00a4ff">${val}</span>`)})})})constvalue2=newRegExp('test_idconese','gi')this.allData=this.detailLi.content.match(value2)if(this.allData&&this.allData.length>0){this.allData.forEach((item,index)=>{this.detailLi.content=this.detailLi.content.replace('test_idconese',`test_${index}idconese`)})}//dom生成完毕后在执行的函数this.$nextTick(function(){if(this.$el.querySelector('#test_0idconese')){this.$el.querySelector('#test_0idconese').scrollIntoView({behavior:'smooth',inline:'nearest',})}//高亮的方法this.upGaGaLiang(val)})}else{this.allData=[]}//判断是否点击了关闭if(x){if(this.searData!==''){this.detailLi.content=this.searData}else{this.searData=this.detailLi.content}}},2.高亮的方法函数(默认第一个高亮):
//高亮upGaGaLiang(val){this.range=document.createRange()constcontainer=document.getElementById('htmlcontent')constallText=container?.innerTextthis.inputValue=valif(allText&&allText.includes(this.inputValue)){//获取所有节点constcontainerAllNode=container.childNodes//用于保存找到的节点this.findNode=[]for(leti=0;i<containerAllNode.length;i){//遍历查询节点if(containerAllNode[i].textContent?.includes(this.inputValue)){this.findNode.push(containerAllNode[i])}}//默认选中第一个if(this.findNode&&this.findNode.length>0){conststartNode=document.getElementById('test_0idconese').firstChildif(startNode){this.range.setStart(startNode,0)this.range.setEnd(startNode,this.ritKeyWord.length)constselection=window.getSelection()selection?.removeAllRanges()selection?.addRange(this.range)}//this.setSelect(0)}}else{}},3.切换上一个和下一个(不卡顿)
pickUp(num){if(this.pickNum>0){this.pickNum=this.pickNum-1if(document.getElementById((`test_${this.pickNum}idconese`))){conststartNode=document.getElementById(`test_${this.pickNum}idconese`).firstChildif(startNode){this.range.setStart(startNode,0)this.range.setEnd(startNode,this.ritKeyWord.length)constselection=window.getSelection()selection?.removeAllRanges()selection?.addRange(this.range)}this.$el.querySelector(`#test_${this.pickNum}idconese`).scrollIntoView({behavior:'smooth',inline:'nearest',})}}elseif(this.pickNum===0){if(document.getElementById('test_0idconese')){conststartNode=document.getElementById('test_0idconese').firstChildif(startNode){this.range.setStart(startNode,0)this.range.setEnd(startNode,this.ritKeyWord.length)constselection=window.getSelection()selection?.removeAllRanges()selection?.addRange(this.range)}this.$el.querySelector('#test_0idconese').scrollIntoView({behavior:'smooth',inline:'nearest',})}}},pickDown(num){if(this.pickNum<this.allData.length-1){this.pickNum=this.pickNum1if(document.getElementById(`test_${this.pickNum}idconese`)){conststartNode=document.getElementById(`test_${this.pickNum}idconese`).firstChildif(startNode){this.range.setStart(startNode,0)this.range.setEnd(startNode,this.ritKeyWord.length)constselection=window.getSelection()selection?.removeAllRanges()selection?.addRange(this.range)}this.$el.querySelector(`#test_${this.pickNum}idconese`).scrollIntoView({behavior:'smooth',inline:'nearest',})}}else{if(this.allData.length&&this.allData.length>0){if(document.getElementById(`test_${(this.allData.length-1)}idconese`)){conststartNode=document.getElementById(`test_${(this.allData.length-1)}idconese`).firstChildif(startNode){this.range.setStart(startNode,0)this.range.setEnd(startNode,this.ritKeyWord.length)constselection=window.getSelection()selection?.removeAllRanges()selection?.addRange(this.range)}}}}},文章内容大致为:通过v-html渲染的页面。
<divref="htmlcontent"class="htmlcontent"id="htmlcontent"v-html="detailLi.content"/>
data中的某些值:
data(){return{inputValue:'',findNode:[],index:-1,range:null,ritKeyWord:'',//搜索的关键词}}关于方法2的知识点参考:http://t.csdn.cn/DT92m