How to loop through the nested DOM tree

I’m working on trying to get the innerHTML or value (depending on the tag) of a tag, but not sure how to loop the nested children tags. I’d like the style to be applied on a tag when it only include “World” in it. Here’s the fiddle link. Could smb help ?

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
<body>
    <h2>Iterave over Children of HTML Element using JavaScript</h2>
    <div id="myElement">
        <p>Hello <span>World</span>!</p>
        <ul>
          <li>List Item</li>
         </ul>
        <div>
          Sample World
          <div>
            Nested Div
               <div>
                 Another Nested Div with World
               </div>
          </div>
        </div>
    </div>
    <br>
    <button type="button" onclick="execute()">Click Me</button>
    <p id="out"></p>
    <script>
    function execute(){
        var element = document.getElementById("myElement");
        var children = element.children;
        for(var i=0; i<children.length; i++){
            var child = children[i];
            console.log(child)
            if (child.innerHTML.includes("World"))
                child.style.color = "red";
        }
    }
    </script>
</body>
</html>

Answer

The solution for this is rather untrivial in my opinion, as both innerHtml and innerText return all child nodes text as well. First, I would do a recursive solution – to look inside all those child nodes. As we need only the parent’s text – we have to remove all the children of the node. And we have to do it without altering the DOM – cloning elements will be out answer here. Third problem arises when it comes to parent’s node style applying to children as well – I will use a helper css class that will keep the text black.

function recursive_execute(el){ 
var element; //out target element
    if(!el){ //if nothing is passed to function we take the root: `myElement`
        element = document.getElementById("myElement");
  }
  else{
    element = el; 
  }
  var children = element.children; 
  if(children.length > 0){
    for(let i = 0; i < children.length; i++){
        let child = children[i];
      recursive_execute(child); //call function for all children of the target element
    }
  }
  
  let item = element.cloneNode(true); //cloning target node
  if(item.children && item.children.length > 0){
    for(let i = 0; i < item.children.length; i++){
        let child = item.children[i];
      if(child.tagName){ //getting rid of children who are tagged (so we don't get rid of text)
        item.removeChild(child);
      }
    }
  }
  if(item.innerHTML && item.innerHTML.includes("World")){ //check if our clone contains the desired word
    element.style.color = "red"
  }else{
    element.className = "helper" //if not - assigning helper class
  }
}
.helper{
  color:black;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
<body>
    <h2>Iterave over Children of HTML Element using JavaScript</h2>
    <div id="myElement">
        <p>Hello <span>World</span>!</p>
        <ul>
          <li>List Item</li>
         </ul>
        <div>
          Sample World
          <div>
            Nested Div
               <div>
                 Another Nested Div with World
               </div>
          </div>
        </div>
    </div>
    <br>
    <button type="button" onclick="recursive_execute()">Click Me</button>
    <p id="out"></p>
</body>
</html>