Search code examples
javascripthtmlreplaceinnerhtmlouterhtml

How replace inner HTML content with mixed inner and outer HTML content that is rendered properly in browsers


My question relates to the following Javascript which is included after the body of a HTML document:

   <script language="javascript">
    function walkText(node) {
      if (node.nodeType == 3) {
        node.data = node.data.replace(/Blah Blah Blah/gi, "<span style=\"font-family: elektora;\">a<span style=\"font-size: 80%\">shen</span> g<span style=\"font-size: 80%\">low</span> g<span style=\"font-size: 80%\">aming</span></span>");
      }
      if (node.nodeType == 1 && node.nodeName != "SCRIPT") {
        for (var i = 0; i < node.childNodes.length; i++) {
          walkText(node.childNodes[i]);
        }
      }
    }
    walkText(document.body);
   </script>

Note that the replacement text contains a mix of both inner and outer HTML content, and is not being rendered accordingly in browsers. It is outputted as raw unprocessed HTML - <span style=\"font-family: elektora;\">a<span style=\"font-size: 80%\">shen</span> g<span style=\"font-size: 80%\">low</span> g<span style=\"font-size: 80%\">aming</span></span> - in browsers.

How do I modify the find-and-replace code to replace in such a way in browsers so as to be respected as mixed inner and outer HTML content. At the moment it replaces the original text string with another text string, whose HTML tags are not rendered in the browser.


Solution

  • The reason for your problem is you are replacing a text node. So the string is not rendering. Try following code block

    function walkText(node) {
    let replacedText = "<span style='font-family: elektora;'>a<span style='font-size: 80%'>shen</span> g<span style='font-size: 80%'>low</span> g<span style='font-size: 80%'>aming</span></span>";
    let pattern = /hhh/gi;
    
      if (node.nodeType == 1 && node.nodeName != "SCRIPT") {
    
      let indx = node.innerHTML.search(pattern, replacedText);      
      if (indx != -1)
      {
          node.innerHTML = node.innerHTML.replace(pattern, replacedText);
      }
      else
      {      
        for (var i = 0; i < node.childNodes.length; i++) {
          walkText(node.childNodes[i]);
        }
       }
      }      
    }
    walkText(document.body);