vue 实现Ctrl+F搜索功能(定位+滚动的效果)

vue 实现Ctrl+F搜索功能(解决掉能搜查标签属性)兼容IE

效果图

<template>
    <div class="app-container">
<el-input
            v-model="searchText"
            placeholder="请输入关键字"
            prefix-icon="el-icon-search"
            clearable
            size="small"
            @keyup.enter.native="search"
          >
          </el-input>
          <el-button
            type="primary"
            size="small"
            icon="el-icon-search"
            @click="search"
          ></el-button>
          <div class="searchRight">
            <span class="item" style="margin-right: 5px">
              {{ num === 0 ? '没有任何结果' : indexNum + 1 + '/' + num }}</span>
            <el-tooltip
              class="item"
              effect="dark"
              content="上一个"
              placement="top"
            >
              <el-button
                icon="el-icon-arrow-up"
                circle
                type="text"
                size="mini"
                @click="prev"
              ></el-button>
            </el-tooltip>
            <el-tooltip
              class="item"
              effect="dark"
              content="下一个"
              placement="top"
            >
              <el-button
                icon="el-icon-arrow-down"
                circle
                type="text"
                size="mini"
                @click="next"
              ></el-button>
            </el-tooltip>
          </div>
</div>
</template>
<script>
export default {
    data() {
        return {
          searchText: '',
          scroll: '',
          index: 1,
          query: '',
          preQuery: '',
          indexNum: 0,
          num: 0,
          main: null,
          showArr: [],
          showIndex: 0,
        }
    },
    mounted() {
    // scroll代表滚动条距离页面顶部距离
    window.addEventListener('scroll', this.dataScroll)
    this.mian = document.querySelector('.log_content')
  },
    methods:{
    // 搜索
    search() {
      this.num = 0
      this.indexNum = 0
      this.query = this.searchText
      // eslint-disable-next-line prefer-const
      // document.querySelector 这里获取标签需要自己换一下
      let main = this.main || document.querySelector('.log_content > .docx-wrapper > .docx')
      var innerHTML = main.innerHTML
      // 如果要兼容IE就使用下面的正则 (谷歌 IE 都可以使用)
      //innerHTML = innerHTML.replace(new RegExp('<[^>]+>', 'g'), function(str) {
        //return str.replace(new RegExp('(<\/?em.*?>)|(<\/?strong.*?>)', 'g'), '')
      //})
      //------ 这行代码不兼容IE
      const emReg1 = new RegExp('<em style="background-color: yellow">', 'g')
      innerHTML = innerHTML.replace(emReg1, '')
      const emReg2 = new RegExp('</em>', 'g')
      innerHTML = innerHTML.replace(emReg2, '')
      const emReg3 = new RegExp('<strong style="background-color: #ff9632">', 'g')
      innerHTML = innerHTML.replace(emReg3, '')
      const emReg4 = new RegExp('</strong>', 'g')
      innerHTML = innerHTML.replace(emReg4, '')
      // ------
      main.innerHTML = innerHTML
      // 设置本次搜索背景色
      if (this.searchText !== '' && this.searchText !== ' ') {
        const reg = new RegExp(this.searchText, 'g')
        const searchText = this.searchText
        var mainInnerHTML = innerHTML.replace(new RegExp('(?=\>).+?(?=\<)', 'g'), function(str) {
          const reg1 = new RegExp('(?=>).+', 'g')
          return str.replace(new RegExp('(>).+', 'g'), function(str2) {
            return str2.replace(reg1, function(str1) {
              return str1.replace(reg, '<em style="background-color: yellow">' + searchText + '</em>')
            })
          })
        })
        main.innerHTML = mainInnerHTML
      }
      // 替换配置
      this.getSearchList()
    },
    getSearchList() {
      // em标签都是被替换的 所以em标签的数量就是搜索到关键字的数量
      const num = document.getElementsByTagName('em').length
      this.num = num
      if (num !== 0) {
        document.getElementsByTagName('em')[0].innerHTML =
          '<strong style="background-color: #ff9632">' +
          this.searchText +
          '</strong>'
        // 滚动到第一个关键字位置
        document.getElementsByTagName('em')[0].scrollIntoView({
          block: 'start',
          behavior: 'smooth'
        })
      }
    },
    dataScroll() {
      this.scroll =
        document.documentElement.scrollTop || document.body.scrollTop
    },
    // 下一个
    next() {
      if (this.num !== 0) {
        for (let i = 0; i < document.getElementsByTagName('em').length; i++) {
          document.getElementsByTagName('em')[i].innerHTML = this.searchText
        }
        if (this.indexNum === this.num - 1) {
          this.indexNum = 0
        } else {
          this.indexNum = this.indexNum + 1
        }
        document.getElementsByTagName('em')[this.indexNum].innerHTML =
          '<strong style="background-color: #ff9632">' +
          this.searchText +
          '</strong>'
        document.getElementsByTagName('em')[this.indexNum].scrollIntoView()
      }
    },
    // 上一个
    prev() {
      if (this.num !== 0) {
        for (let i = 0; i < document.getElementsByTagName('em').length; i++) {
          document.getElementsByTagName('em')[i].innerHTML = this.searchText
        }
        if (this.indexNum === 0) {
          this.indexNum = this.num - 1
        } else {
          this.indexNum = this.indexNum - 1
        }
        document.getElementsByTagName('em')[this.indexNum].innerHTML =
          '<strong style="background-color: #ff9632">' +
          this.searchText +
          '</strong>'
        document.getElementsByTagName('em')[this.indexNum].scrollIntoView()
      }
    }
    }
}
</script>

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值