My goal is to highlight case-insensitive words in the DOM. For instance, I'd like to highlight stackoverflow with
<mark>stackoverflow</mark>
and Google
with <mark>Google</mark>
To achieve this, my approach involves utilizing Document.createNodeIterator()
which specifically filters out non-text nodes.
window.onload = function() {
getChildren(document.body);
}
function getChildren(mytag) {
const nodeIter = document.createNodeIterator(
mytag,
NodeFilter.SHOW_TEXT,
(node) => {
return NodeFilter.FILTER_ACCEPT
}
);
const mark = document.createElement("mark")
let node = nodeIter.nextNode();
while (node) {
const parent = node.parentElement;
const innerHTML = parent.innerHTML;
const word = "stackoverflow"
const regex = new RegExp(`(${word})`, 'ig');
parent.removeChild(node)
parent.innerHTML = innerHTML.replace(regex, "<mark>$1</mark>");
node = nodeIter.nextNode()
}
}
<h1>Iterating DOM in JavaScript</h1>
<p>
A paragraph.
</p>
<div>
<a href="https://stackoverflow.com/">Stackoverflow</a> is QA website.
</div>
<ul>
<li>Stackoverflow</li>
<li>Google</li>
<li>Apple</li>
</ul>
The existing code seems to have a flaw as it iterates infinitely. Interestingly, changing the highlighted word from stackoverflow
to
<mark>duckduckgo</mark>
prevents infinite iteration. How can this issue be resolved?