1

I'm trying to replace all instances of "foo" on a page with "bar", but to exclude instances occurring within image or URL links.

The current code I have is a simple replace:

document.documentElement.innerHTML = document.documentElement.innerHTML.replace(/foo/g, "bar");

But it breaks images and links containing "foo" in the address.

I'm looking for a regular expression replacement that will take the following:

foo                       
barfoo                    
<a href="foo.com">foo</a> 
<img src="foo.jpg">       

And give me:

bar
barbar
<a href="foo.com">bar</a>
<img src="foo.jpg">

If this can't be accomplished with regex in JavaScript, would there be a more elegant way to only run the replacement against non-URL strings?

2 Answers2

1

There are 2 problems to solve.

Firstly, you need to get all the text nodes. This is a problem in and of itself.

This thread on stackoverflow discusses some techniques.

getElementsByTagName() equivalent for textNodes

Once you have your text nodes, you can run your regex on each node, and be fairly certain that you got everything.

Community
  • 1
  • 1
speciesUnknown
  • 1,644
  • 2
  • 14
  • 27
1

Yeah, you're not going to want to use regex to do this. What you want to do is replace the text of every text node in your DOM tree. Try something like this.

var allElements = document.getElementsByTagName("*"); // Get every element.

for (var i = 0; i < allElements.length; i++) { 
    var children = allElements.item(i).childNodes; 

    for (var j = 0; j < children.length; j++) { 
        if (children[j].nodeType === 3 /* is this node a text node? */) { 
            children[j].nodeValue = children[j].nodeValue.replace(/* run your replacement regex here */). 
        } 
    } 
}
thedayturns
  • 9,723
  • 5
  • 33
  • 41
  • Or just `document.evaluate("//text()", ...)`. Or use `TreeWalker`. –  Jan 14 '17 at 07:32
  • 1
    nodeType was the missing link to fixing my issue. I hadn't even heard of it (again, super new to JS) so I didn't even know to look into it. Thank you! – Michael Veenstra Jan 22 '17 at 02:52