skip to Main Content
<p>Non-highlighted part. Only this part must be highlighted. Non-highlighted part.</p>

How do I highlight only "Only this part must be highlighted." part out of the complete text content of the <p> tag?

I was trying to search for a text and then highlight it using the following code.

var xpath = "//*[contains(text(), 'Only this part must be highlighted.')]";
var matchingElements = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

const numberOfElements = matchingElements.snapshotLength;

for (let i = 0; i < numberOfElements; i++) {
    const element = matchingElements.snapshotItem(i);

    // Do something with each element:
    console.log(element.tagName, element.textContent);

    // Example: Highlight the element
    element.style.backgroundColor = "yellow";
}

This code highlights the complete element where the text is found. In this case, the complete <p> tag will be highlighted. How do I highlight only the text found?

2

Answers


  1. You can do something like this. your can select the element and search and wrap the span around your required highlighted text.

    const elem = document.getElementsByTagName('p')[0];
    const textToSearch = "Only this part must be highlighted"
    elem.innerHTML = elem.textContent.replace(textToSearch, `<span class="highlight">${textToSearch}</span>`);
    .highlight {
      color: red;
    }
    <p>Non-highlighted part. Only this part must be highlighted. Non-highlighted part.</p>
    Login or Signup to reply.
  2. Since your original code only works with text nodes, here is an implementation that finds all text nodes (using a treeWalker), then filters those that match the text you want to find and finally creates a range of that text and wraps it with a span element and adds a class to it.

    I have added a utility method to remove all highlights as well.

    The code to select the text nodes using a TreeWalker is taken from Find all text nodes in HTML page so credits belong to @Phrogz for that.

    function highlightContent(textToHighlight) {
      const allTextNodes = textNodesUnder(document.body);
      var matchingElements = allTextNodes.filter(textNode => textNode.textContent.includes(textToHighlight));
    
    
      for (let textNode of matchingElements) {
        const textOffset = textNode.textContent.indexOf(textToHighlight);
    
        const range = new Range();
        range.setStart(textNode, textOffset);
        range.setEnd(textNode, textOffset + textToHighlight.length);
        
        const wrapper = document.createElement('span');
        wrapper.classList.add('highlighted');
        range.surroundContents(wrapper);
      }
    
    }
    
    function unHighlightContent() {
      const highlights = document.querySelectorAll('.highlighted');
    
      console.log([...highlights].map(n => n.parentNode));
      for (let highlight of highlights) {
        highlight.replaceWith(highlight.childNodes[0]);
      }
    }
    
    highlightContent('Only this part must be highlighted.');
    //unHighlightContent();
    
    
    
    function textNodesUnder(el) {
      const children = [] // Type: Node[]
      const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, (node) => node.parentNode.nodeName !== 'SCRIPT')
      while (walker.nextNode()) {
        children.push(walker.currentNode)
      }
      return children
    }
    .highlighted {
      background: yellow;
    }
    <p>Non-highlighted part. Only this part must be highlighted. Non-highlighted part.</p>
    
    <p>Non-highlighted part. Only this part must be highlighted. Non-highlighted part.</p>
    
    <p>Non-highlighted part. Only this part must be highlighted. Non-highlighted part.</p>
    
    <p>Non-highlighted part. Only this part must be highlighted. Non-highlighted part.</p>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search