I'm looking to replace text in a webpage (any webpage I want to run it on) using JavaScript. I'm not an expert in JavaScript, so I am sort of lost. If I can help it I would like to avoid jQuery.
Through Google, I've found this stackoverflow question. But when I inject document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');
into a webpage it sort of messes the page up. It seems to make the page revert to basic text and formatting.
Also, I'm wondering if the regex code from here, could be used. Again, I really am not sure how to use it. What it would do is replace only webpage text - not links or filenames.
I'm using Google Chrome incase that matters.
I'm looking to replace text in a webpage (any webpage I want to run it on) using JavaScript. I'm not an expert in JavaScript, so I am sort of lost. If I can help it I would like to avoid jQuery.
Through Google, I've found this stackoverflow question. But when I inject document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');
into a webpage it sort of messes the page up. It seems to make the page revert to basic text and formatting.
Also, I'm wondering if the regex code from here, could be used. Again, I really am not sure how to use it. What it would do is replace only webpage text - not links or filenames.
I'm using Google Chrome incase that matters.
Share Improve this question edited May 23, 2017 at 11:47 CommunityBot 11 silver badge asked Aug 27, 2013 at 20:07 NumeriNumeri 1,0474 gold badges14 silver badges32 bronze badges 7 | Show 2 more comments2 Answers
Reset to default 13You could perform your repleacements on all the just the text nodes in the DOM:
function replaceTextOnPage(from, to){
getAllTextNodes().forEach(function(node){
node.nodeValue = node.nodeValue.replace(new RegExp(quote(from), 'g'), to);
});
function getAllTextNodes(){
var result = [];
(function scanSubTree(node){
if(node.childNodes.length)
for(var i = 0; i < node.childNodes.length; i++)
scanSubTree(node.childNodes[i]);
else if(node.nodeType == Node.TEXT_NODE)
result.push(node);
})(document);
return result;
}
function quote(str){
return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}
}
Quote function borrowed from this answer.
Usage:
replaceTextOnPage('hello', 'hi');
Note that you will need to SHIM forEach in older browsers or replace that code with a loop like so:
var nodes = getAllTextNodes();
for(var i = 0; i < nodes.length; i++){
nodes[i].nodeValue = nodes[i].nodeValue.replace(new RegExp(quote(from), 'g'), to);
}
Recently, I had to exercise a similar problem, and I came up with something similar to this:
<!DOCTYPE html>
<html>
<head>
<title>HTML JS REPLACE</title>
<script type="text/javascript">
function convert(elem) {
var content = document.getElementById(elem).innerHTML; // get HTML content for the given element
var pattern = new RegExp(/hello/gi);
content = content.replace(pattern,'hi');
document.getElementById(elem).innerHTML = content; // put the replace content back
}
</script>
</head>
<body>
<div id="content">
Some text that includes both hello and hi. And a hello.
</div>
<script type="text/javascript">
window.onload = convert('content');
</script>
</body>
</html>
The result will be that you will get a page saying this:
Some text that includes both hi and hi. And a hi.
while the original source still says:
Some text that includes both hello and hi. And a hello.
The tricky bits are really just a few - first, you want the window.onload trigger to be included at the bottom of body, so the DOM loads fully before running any JS on it. Second, you must have a top-level block element that you assign a unique ID which you can reference from JS. Third, the convert function uses a regular expression, which executes a global case-insensitive replace of the string "hello" by changing it to "hi".
Your specific application may require to instead capture all of the occurences and then parse them in a loop, which may (or may not) cause some performance issues. Be careful :)
innerHTML
it will regenerate all elements and lose event bindings. – zzzzBov Commented Aug 27, 2013 at 20:10