Skip to main content
1 of 6
Mike Brant
  • 9.6k
  • 13
  • 23

Your logic currently does a lot more work that it needs to do.

First, you are iterating every element in DOM and then iterating on every child element of those (which is actually duplicate work, since all nested tags would already be present in elements). This is especially problematic in that you are really only interested in text nodes. So, your first order of business, is to get only those nodes you care about.

Perhaps check out this StackOverflow post on this topic - http://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page.

I personally like the TreeWalker approach in the accepted answer.

Now that you have a good flattened representation of these text nodes, you can just iterate through and directly modify them.

// build word map
var wordMap = {
   'match value' => 'replace value',
   // etc.
}

// build single regex
var regex = new RegExp(Object.keys(wordMap).join("|"),"gi");

// get text nodes
var textNodes = ...; // derive similar to linked SO question above.

// iterate text nodes and modify in place
for (var i = 0, len = textNodes.length; i < len; i++) {
    textNodes[i].nodeValue = textNodes[i].nodeValue.replace(regex, function(match) {
        return wordMap[match];
    });
}

This example above allows would have you modifying the nodes in place rather than having to do any DOM replacements.

Mike Brant
  • 9.6k
  • 13
  • 23