I am trying to get certain words to highlight in a page. To accomplish this, I want to find all text nodes and replace only the specific word with a span that will highlight it. The code appears to search and find the words in the text nodes properly, but the replace is not working. I get this:
<span style="background-color: #FBC300;">foo</span>
And I want to get this:
foo (with a highlighted background)
function toRegExp(text) {
return new RegExp(text, 'g');
}
function toSpan(text) {
return '<span style="background-color: #FBC300;">' + text + '</span>';
}
function replaceText(squery, node) {
node = node || document.getElementById("mainContent"); // base node
for (node=node.firstChild;node;node=node.nextSibling){
if (node.nodeType==3) {
if (node.innerHTML) {
node.innerHTML = node.innerHTML.replace(toRegExp(squery), toSpan(squery));
} else { // support to IE
node.nodeValue = node.nodeValue.replace(toRegExp(squery), toSpan(squery));
}
}
else replaceText(squery, node);
}
}
A text node can't contain elements, so you'll need to take the text node and split it into multiple nodes. For example, if you want to highlight world
in hello world
, you'll need to split it into a text node hello
and an element <span>world</span>
, which you can then style. Something like this:
function replaceText(squery, node) {
node = node || document.getElementById("mainContent"); // base node
for (node = node.firstChild; node; node=node.nextSibling) {
if (node.nodeType == 3 && node.nodeValue) {
var pieces = node.nodeValue.split(squery);
if (pieces.length > 1) {
// Split this node up into pieces
for (var i = 0; i < pieces.length - 1; i++) {
node.parentNode.insertBefore(document.createTextNode(pieces[i]), node);
var span = document.createElement('span');
span.style.backgroundColor = '#FBC300';
span.innerText = squery;
node.parentNode.insertBefore(span, node);
}
node.nodeValue = pieces[pieces.length - 1];
}
}
else
replaceText(squery, node);
}
}