skip to Main Content

I used this piece of code, to replace text strings in my webpage:

   function walkText(node) {
      if (node.nodeType == 3) {
        node.data = node.data.replace(/Villa/g, "Replaced");
        node.data = node.data.replace(/Apartment/g, "Replaced2");
      }
      if (node.nodeType == 1 && node.nodeName != "SCRIPT") {
        for (var i = 0; i < node.childNodes.length; i++) {
          walkText(node.childNodes[i]);
        }
      }
    }
    walkText(document.body);
Villa
Apartment

This works fine on static content, but will not work on content that gets loaded dynamically through ajax. Is there a workaround to make this work on text that is not static/not loaded on page load?

Thanks.

2

Answers


  1. A basic, simple way to do this is to observe your page with MutationObserver. Below I have created a very simple example for this:

    function walkText( node ){
      
      // I needed to modify this to prevent potentially infinite loops
      // by replacing the data it could trigger another mutation event
      if( node.nodeType == 3 ){
      
        const newData = node.data
          .replaceAll( /Villa/, "Replaced" )
          .replaceAll( /Apartment/, "Replaced2" );
        
        if( node.data !== newData ) node.data = newData;
        
      }
      
      if( node.nodeType == 1 && node.nodeName != "SCRIPT" ){
      
        for( const child of node.childNodes ) walkText( child );
        
      }
      
    }
    
    new MutationObserver(entries => {
        
       entries.forEach(entry => {
       
          walkText( entry.target );
        
       });
      
    }).observe( document.body, { characterData: true, childList: true });
    
    
    
    document.addEventListener( 'click', event => {
    
      document.body.appendChild( document.createElement( 'div' ) ).textContent = 'There is Apartment about Villa';
      
    })

    The only modifications I had to make is to ensure that the text only updates when necessary, to prevent triggering an infinite loop. Otherwise, with this, it seems pretty efficient.

    Docs: MutationObserver (MDN)

    Login or Signup to reply.
  2. Use MutationObserver for added nodes and replace the text:

    https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

    Don’t forget to disconnect the observer when you replace text otherwise you will react on own mutations and could go into an infinite loop.

    function changeNodes(){
      document.querySelectorAll('div').forEach(div => 
        div.textContent = 'Villa or Apartment'
      );
    }
    
    
    function addNodes(){
      const div = document.createElement('div');
      div.textContent = 'Villa or Apartment';
      document.body.appendChild(div);
    }
    
    const observer = new MutationObserver(mutations => {
      observer.disconnect();
      
      for(const mutation of mutations){
        [...mutation.addedNodes].forEach(walkText);
      }
      
      observer.observe(document.body, {childList:true, subtree:true});
    });
    
    observer.observe(document.body, {childList:true, subtree:true});
    
    function walkText(node) {
      if (node.nodeType == 3) {
        node.data = node.data.replace(/Villa/g, "Replaced");
        node.data = node.data.replace(/Apartment/g, "Replaced2");
      }
      if (node.nodeType == 1 && node.nodeName != "SCRIPT") {
        for (var i = 0; i < node.childNodes.length; i++) {
          walkText(node.childNodes[i]);
        }
      }
    }
    <button onclick="addNodes()">Add nodes</button>
    <button onclick="changeNodes()">Change nodes</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search