Search code examples
javascripthtmldomdom-traversal

Faster way of replacing text in all dom elements?


I'm trying to replace all text in between tags and I want to know the fastest way of doing so.

An example would be trying to replace all text with the arbitrary string helloWorld, so that this:

<div>
    <div>
        RandomText1
        <div>
            RandomText2
        </div>
    </div>
</div>

Becomes this:

<div>
    <div>
        helloWorld
        <div>
            helloWorld
        </div>
    </div>
</div>

My current approach would be :

  • Do Depth-first search (DFS) on DOM
  • For each element parse and determine which part is text and which part is an element.
  • For the part that is text replace it.

This to me would be really slow, especially trying to do this for a large document and having to repeat the process many times. Is there a faster way?


Solution

  • You don't need to parse each element to find text nodes, you can just recursively traverse childNodes property of an element

    var newText = 'hello world';
    function replaceTextNodes(node) {
      node.childNodes.forEach(function(el) {
        if (el.nodeType === 3) {  // If this is a text node, replace the text
          if (el.nodeValue.trim() !== "") { // Ignore this node it it an empty text node
            el.nodeValue = newText;
          }
        } else { // Else recurse on this node
          replaceTextNodes(el);
        }
      });
    }
    
    var onClick = replaceTextNodes.bind(null, document.querySelector('#container'));
    document.querySelector('#replace').addEventListener('click', onClick);
    <div id='container'>
      <div>
        RandomText1
        <div>
          RandomText2
          <ul>
            <li>RandomText3</li>
          </ul>
        </div>
      </div>
    </div>
    <button id="replace">Replace</button>