当前位置:

忽略html标签特殊和amp;#等。替换过滤处理,搜索关键字并高亮显示,带锚点定位实现ctrl+F的功能。两种方法正则表达式,range方法

访客 2024-04-25 1425 0

目录方法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=0
  • if(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){
  • //这边是判断乱码过滤(&#36830;&#25509;&#25968;&#25454;&#24211;&#25104;&#21151;&#65281;)正则校验除了这种的之外
  • 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=this
  • this.pickNum=0
  • if(val!==''){
  • if(this.searData!==''){
  • this.detailLi.content=this.searData
  • }else{
  • this.searData=this.detailLi.content
  • }
  • constreg=newRegExp(val,'g')
  • //正则校验先乱码过滤(&#36830;&#25509;&#25968;&#25454;&#24211;&#25104;&#21151;&#65281;)正则校验除了这种的之外
  • 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{
  • ////这边是判断乱码过滤(&#36830;&#25509;&#25968;&#25454;&#24211;&#25104;&#21151;&#65281;)正则校验除了这种的之外
  • //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.length
  • varstr=''
  • 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-1
  • this.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.pickNum1
  • this.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=this
  • this.pickNum=0
  • if(val!==''){
  • if(this.searData!==''){
  • this.detailLi.content=this.searData
  • }else{
  • this.searData=this.detailLi.content
  • }
  • constreg=newRegExp(val,'g')
  • //正则校验先乱码过滤(&#36830;&#25509;&#25968;&#25454;&#24211;&#25104;&#21151;&#65281;)正则校验除了这种的之外
  • 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?.innerText
  • this.inputValue=val
  • if(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').firstChild
  • if(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-1
  • if(document.getElementById((`test_${this.pickNum}idconese`))){
  • conststartNode=document.getElementById(`test_${this.pickNum}idconese`).firstChild
  • if(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').firstChild
  • if(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.pickNum1
  • if(document.getElementById(`test_${this.pickNum}idconese`)){
  • conststartNode=document.getElementById(`test_${this.pickNum}idconese`).firstChild
  • if(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`).firstChild
  • if(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

    发表评论

    • 评论列表
    还没有人评论,快来抢沙发吧~