I'm looking for a way to search a node's innerText for a matching string. Then wrap the matching text in a <span>
.
Requirements:
1 > The node may contain html tags and I would like those tags to be maintained within the matching text selection.
2 > I would also like this to be case sensitive on the matching text.
Ex:
This is my <strong>content</strong> to search.
I would like to find "my content to search"
Match and wrap "my <strong>content</strong> to search"
in a span resulting in:
This is <span>my <strong>content</strong> to search</span>.
This code only searches for an exact match within a node and doesn't match if there's html tags (because those are additional child nodes):
/* Prompt for search */
var text = prompt("Search for:", "");
if (text == null || text.length == 0) return;
/* Remove highlighted results */
var spans = document.getElementsByClassName("labnol");
if (spans) {
for (var i = 0; i < spans.length; i++) {
spans[i].style.backgroundColor = "transparent";
}
}
function searchWithinNode(node, te, len) {
var pos, skip, spannode, middlebit, endbit, middleclone;
skip = 0;
if (node.nodeType == 3) {
pos = node.data.indexOf(te);
if (pos >= 0) {
spannode = document.createElement("span");
spannode.setAttribute("class", "labnol");
spannode.style.backgroundColor = "yellow";
middlebit = node.splitText(pos);
endbit = middlebit.splitText(len);
middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
} else if (node.nodeType == 1 && node.childNodes && node.tagName.toUpperCase() != "SCRIPT" && node.tagName.toUpperCase != "STYLE") {
for (var child = 0; child < node.childNodes.length; ++child) {
child = child + searchWithinNode(node.childNodes[child], te, len);
}
}
return skip;
}
searchWithinNode(document.body, text, text.length);