html片段搜索关键词高亮处理函数

133 阅读1分钟

高亮关键词替换

踩坑比较多,html的处理可能是之前不是接触很多。踩了一些坑,比如替换掉样式什么的, 现在直接贴出来给大家当个参考,

/***
 * @description: 正则转义处理
 * @param {String} string
 * @return {String}
 ***/
function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

/***
 * @description: 高亮关键词
 * @param {String} html  html字符串
 * @param {String} keyword 关键词
 * @return {String}
 ***/
const changeContent = (html, keyword) => {
  let index = 0;
  if (
    !keyword ||
    typeof keyword !== 'string' ||
    keyword.trim() === '' ||
    /<\/?[a-z][\s\S]*>/i.test(keyword)
  ) {
    console.error('Invalid searchText');
    return html;
  }

  const escapedSearchText = escapeRegExp(keyword);
  const regex = new RegExp(escapedSearchText, 'gi');

  const parser = new DOMParser();
  const doc = parser.parseFromString(html, 'text/html');

  function processNode(node) {
    if (node.nodeType === Node.TEXT_NODE) {
      const fragment = document.createDocumentFragment();
      let lastIdx = 0;
      node.textContent.replace(regex, (match, idx) => {
        const before = node.textContent.slice(lastIdx, idx);
        const span = document.createElement('span');
        span.className = 'keyword';
        span.id = `specSpan${index++}`; // 这里添加index是为了搜索定位使用,可忽略
        span.textContent = match;

        fragment.appendChild(document.createTextNode(before));
        fragment.appendChild(span);

        lastIdx = idx + match.length;
      });
      fragment.appendChild(
        document.createTextNode(node.textContent.slice(lastIdx))
      );
      node.parentNode.replaceChild(fragment, node);
    } else if (node.nodeType === Node.ELEMENT_NODE) {
      Array.from(node.childNodes).forEach(processNode);
    }
  }

  Array.from(doc.body.childNodes).forEach(processNode);

  return doc.body.innerHTML;
};

image.png 里面涉及到的知识点主要是DOMParser,平时可能不常用, 链接如下

DOMParser-mdn