There is no need to run a replacement over the entire HTML. At best it works by accident, there is a big chance it replaces something important. Moreover, this will re-parse the entire DOM and re-insert it which is what most likely breaks the entire page as this can potentially wipe out event listeners and reset a lot of other things.
The correct way would be to only replace the text in text nodes. Use a TreeWalker
(constructed via document.createTreeWalker
to that effect.
Example application that replaces the word "foo" with something else of choice:
function replace(oldWord, newWord) {
const regex = new RegExp(`\\b${oldWord}\\b`);
//create a TreeWalker that goes only over text nodes
const treeWalker = document.createTreeWalker(
document.body, // start node
NodeFilter.SHOW_TEXT, // filter out anything but text nodes
{
// additional filtering - only where the text matches the replacement
acceptNode: node => regex.test(node.textContent)
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_SKIP
}
);
//go over matching nodes...
for (
let currentNode = treeWalker.nextNode();
currentNode != null;
currentNode = treeWalker.nextNode()
) {
debugger;
// ...and replace their content
currentNode.nodeValue = currentNode.textContent.replaceAll(new RegExp(regex, "g"), newWord);
}
}
document.querySelector("button")
.addEventListener("click", () => {
const replacement = document.querySelector("#replacement").value;
replace("foo", replacement);
});
div.foo {
background: yellow;
}
span.foo,
span[data-foo],
[data-custom-attribute="foo"] {
text-decoration: underline;
}
<div class="foo bar">
<span class="foo">Lorem ipsum</span> foo <span data-foo="customvalue">dolor sit amet</span>, <span data-foo="customvalue">consectetur foo adipiscing foo elit</span>, <span>foo</span> <span data-custom-attribute="foo">sed do eiusmod tempor incididunt ut labore</span> et dolore magna aliqua.
<hr/>
<div>the rest will not be replaced as the word is inside other letters</div>
<div>foobar</div>
<div>barfoo</div>
<div>barfoobar</div>
</div>
<br/>
<label for="replacement">Replace with:</label>
<input type="text" placeholder="replacement" value="banana" id="replacement" />
<br />
<button type="button">replace</button>