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.
Asked
Active
Viewed 242 times
2

Segmentation fault
- 115
- 6
-
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 Answers
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