vue 全局搜索关键词高亮

本文介绍了如何使用Vue的自定义指令实现搜索关键词在页面内容中的高亮显示,尽管存在性能影响,但仍提供了一种解决方案。
摘要由CSDN通过智能技术生成

通过自定义指令, 实现搜索关键词高亮。通过自定义指令, 遍历当前元素及其子元素, 如果其内容包含搜索的关键词, 则创建新的dom元素以实现高亮(当前这种方式有一定的弊端, 因为进行dom元素的操作会导致性能下降, 如果有更好的方式, 欢迎留言)。

最终实现效果:

<template>
  <div>
    <div v-keyword-highlight="globalKeyword">
      <h1>关键字高亮</h1>
      <div>关键字高亮</div>
      <div>
        <div>关键字高亮</div>
        <div>
          <p>关键字高亮</p>
          <span>有关键字</span>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { nextTick } from "vue";
export default {
  data() {
    return {
      globalKeyword: "关键", //搜索关键词
    };
  },
  directives: {
    // 全局搜索关键词高亮
    "keyword-highlight": {
      mounted: function(el, binding) {
        const searchText = binding.value; // 从指令值获取要搜索的文字
        const maxDepth = 10; // 最大递归深度,防止过深的遍历
        // 递归函数,用于遍历DOM树并高亮文本
        function traverseAndHighlight(node, depth) {
          if (depth > maxDepth) {
            return; // 达到最大深度,停止遍历
          }
          if (node.nodeType === Node.TEXT_NODE) {
            const newNodeText = node.nodeValue.replace(
              new RegExp(searchText, "gi"), // 'gi' 标志表示不区分大小写和全局搜索
              (match) => `<span class='global-highlight'>${match}</span>`
            );

            if (newNodeText !== node.nodeValue) {
              // 创建新的文本节点或HTML节点
              const newNode = document.createRange().createContextualFragment(`<span>${newNodeText}</span>`).firstChild;
              node.parentNode.replaceChild(newNode, node);
            }
          } else if (node.nodeType === Node.ELEMENT_NODE && node.childNodes.length && depth < maxDepth) {
            // 递归处理子节点,但限制递归深度
            for (let i = node.childNodes.length - 1; i >= 0; i--) {
              traverseAndHighlight(node.childNodes[i], depth + 1);
            }
          }
        }

        // 在nextTick中执行,确保DOM已经准备好
        nextTick(() => {
          traverseAndHighlight(el, 1); // 从当前元素开始遍历
        });
      },
    },
  },
  created() {},
  mounted() {},
  methods: {},
  beforeUnmount() {},
};
</script>
<style>
.global-highlight {
  color: #2b62e2;
}
</style>

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值