0
votes

I have an element that might be <p> or <div> or any other element. I want to get all textnodes of all the element with it's respective text .

var nav = document.getElementById('mynav');
function all(el){
     var io = el.getElementsByTagName('*');
        for (var i = 0; i < io.length; i++) {
            var ex = io[i];
            if (ex.firstChild.data.trim() !== '') {
              console.log(ex.firstChild)
            }
          } 
}

all(nav);
<div id="mynav">
  text1
  <div style="border:1px solid red; height:100px;">
     text2
       <div style="border:1px solid green; height:80px;">
         text3
           <div style="border:1px solid orange; height:60px;">
             <div style="border:1px solid blue; height:40px;">
               text5
             </div>
             text4
           </div>
       </div>
  </div>   
</div>

What my code does?

My above program gives three textnodes containing text( text2 , text3 and text5).

What I am trying to do?

I want to get all the textnodes containing all text i.e(text1 , text2 , text3, text4 and text5) even though my text(i.e: text4) is at the back of div contaning text5.

I think it is possible by using array of childNodes of an elements but not sure.

How can we solve this problem please help me.

Please don't use jquery.

2

2 Answers

2
votes

If you use the DOM .createTreeWalker() method, we can find all the text nodes pretty easily.

.createTreeWalker() is going to be faster than most other methods.

You will notice that even the whitespace content will be included in the results (which is, of course, correct because white space is still text). But, if you don't want that, you can call .trim() on the .nodeValue to clean that up.

function textNodesUnder(el){
  var n, a=[];  // Text nodes will be stored here
  
  // Create TreeWalker object that only looks for text nodes
  var walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
  
  // Loop until we are out of nodes
  while(n = walk.nextNode()) {
    a.push(n);      // Add found text node to array
  }
  return a;  // Return the array
}

// Run function and store returned array
var textNodes = textNodesUnder(document.getElementById('mynav'));

// Loop over the results
textNodes.forEach(function(node){
  console.log(node.nodeValue);
});
<div id="mynav">
  text1
  <div style="border:1px solid red; height:100px;">
     text2
       <div style="border:1px solid green; height:80px;">
         text3
           <div style="border:1px solid orange; height:60px;">
             <div style="border:1px solid blue; height:40px;">
               text5
             </div>
             text4
           </div>
       </div>
  </div>   
</div>
0
votes

You can try next code:

var nav = document.getElementById('mynav');

getAllTextNodes = function(node) {
      if(node && node !== null) {
          var all = [];
          if(node.nodeType === 3) {
              all.push(node);
          } else {
              for(node = node.firstChild; node; node = node.nextSibling) {
                  if(node.nodeType == 3) all.push(node);
                  else all = all.concat(getAllTextNodes(node));
              }
          }
          return all;
      } else {
          return [];
      }
  };
  console.log(getAllTextNodes(nav));
<div id="mynav">
  text1
  <div style="border:1px solid red; height:100px;">
     text2
       <div style="border:1px solid green; height:80px;">
         text3
           <div style="border:1px solid orange; height:60px;">
             <div style="border:1px solid blue; height:40px;">
               text5
             </div>
             text4
           </div>
       </div>
  </div>   
</div>

I tested it in codepen:https://codepen.io/piotrazsko/pen/rJepEB