How to highlight text using javascript

后端 未结 13 2241
名媛妹妹
名媛妹妹 2020-11-22 02:32

Can someone help me with a javascript function that can highlight text on a web page. And the requirement is to - highlight only once, not like highlight all occurrences of

13条回答
  •  温柔的废话
    2020-11-22 02:56

    None of the other solutions really fit my needs, and although Stefan Steiger's solution worked as I expected I found it a bit too verbose.

    Following is my attempt:

    /**
     * Highlight keywords inside a DOM element
     * @param {string} elem Element to search for keywords in
     * @param {string[]} keywords Keywords to highlight
     * @param {boolean} caseSensitive Differenciate between capital and lowercase letters
     * @param {string} cls Class to apply to the highlighted keyword
     */
    function highlight(elem, keywords, caseSensitive = false, cls = 'highlight') {
      const flags = caseSensitive ? 'gi' : 'g';
      // Sort longer matches first to avoid
      // highlighting keywords within keywords.
      keywords.sort((a, b) => b.length - a.length);
      Array.from(elem.childNodes).forEach(child => {
        const keywordRegex = RegExp(keywords.join('|'), flags);
        if (child.nodeType !== 3) { // not a text node
          highlight(child, keywords, caseSensitive, cls);
        } else if (keywordRegex.test(child.textContent)) {
          const frag = document.createDocumentFragment();
          let lastIdx = 0;
          child.textContent.replace(keywordRegex, (match, idx) => {
            const part = document.createTextNode(child.textContent.slice(lastIdx, idx));
            const highlighted = document.createElement('span');
            highlighted.textContent = match;
            highlighted.classList.add(cls);
            frag.appendChild(part);
            frag.appendChild(highlighted);
            lastIdx = idx + match.length;
          });
          const end = document.createTextNode(child.textContent.slice(lastIdx));
          frag.appendChild(end);
          child.parentNode.replaceChild(frag, child);
        }
      });
    }
    
    // Highlight all keywords found in the page
    highlight(document.body, ['lorem', 'amet', 'autem']);
    .highlight {
      background: lightpink;
    }

    Hello world lorem ipsum dolor sit amet, consectetur adipisicing elit. Est vel accusantium totam, ipsum delectus et dignissimos mollitia!

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam, corporis. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium autem voluptas perferendis dolores ducimus velit error voluptatem, qui rerum modi?

    I would also recommend using something like escape-string-regexp if your keywords can have special characters that would need to be escaped in regexes:

    const keywordRegex = RegExp(keywords.map(escapeRegexp).join('|')), flags);
    

提交回复
热议问题