2

I'm writing a browser extension using javascript to highlight key words. So far I have filtered the DOM tree to get all the leaf nodes. But I have problems modifying these nodes because they are leaf nodes (nodeType == 3). node.nodeValue = '<em>keyword</em> is highlighted' doesn't work because angle brackets are escaped. replaceChild can't work either since something like '<em>keyword</em> is highlighted' is not a single node but actually a collection of nodes and I don't want to wrap them into one node.

  • You are actually wanting to append a new node here with a tag of `` so append that to the node in question, add the contained `keyword` to the new node and then append the other text to the `leaf` – Rob Schmuecker Aug 05 '14 at 10:45

1 Answers1

3

Some basic DOM manipulation will do it. Use the text node splitText() method twice to create three text nodes, move the middle text node containing the keyword into your highlight element and the insert your <em> element in between the remaining two text nodes.

Example

Live demo: http://jsfiddle.net/6228e/

HTML:

<div id="example">This text contains a keyword to highlight</div>

JavaScript to highlight the keyword:

var div = document.getElementById("example");
var textNode = div.firstChild;
var keyword = "keyword";
var keywordIndex = textNode.data.indexOf(keyword);
if (keywordIndex > -1) {
    // First, split at the start of the keyword
    var keywordTextNode = textNode.splitText(keywordIndex);

    // Now split off the section after the keyword
    var textNodeAfterKeyword = keywordTextNode.splitText(keyword.length);

    // We now have three text nodes containing the text before the keyword,
    // the keyword itself and the text after the keyword.

    // Create the highlight element and put the keyword text node inside it
    var highlightEl = document.createElement("em");
    highlightEl.appendChild(keywordTextNode);

    // Insert the highlight element and we're done
    div.insertBefore(highlightEl, textNodeAfterKeyword);
}

This only works for the specific case of an element containing a single text node containing a single keyword. For a more general solution, see

https://stackoverflow.com/a/10618517/96100

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536