0

I am traversing this DOM:

     <ul>
        <li class="item">
           <span class="category">
              most occurring text
           </span>
        </li>
        <li class="item">
           <span class="category">
              some text
           </span>
        </li>
        <li class="item">
           <span class="category">
              some text
           </span>
        </li>
        <li class="item">
           <span class="category">
              most occurring text
           </span>
        </li>
        <li class="item">
           <span class="category">
              most occurring text
           </span>
        </li>
     </ul>

With the following code:

var myNodelist = Array.from(document.querySelectorAll(".category"));
var obj = {};

for(var i = 0; i < myNodelist.length; i++){
    //convert array to object with unique elements and number of times 
    each element is repeated
    var x = myNodelist[i].innerHTML;
    //console.log(x);

    if(!obj[x]){
       obj[x] = 1;
    } else {
       obj[x]++;
    }
 }

 var index = 0;
 var max = 0;

 for(var obIndex in obj) {
    // Traverse the object to get the element
    if(obj[obIndex] > max) {
       max = obj[obIndex];
       index = obIndex.replace(" ", "");
    }
 }

 console.log(index + " is max time repeated: " + max + " times." );

 var v = document.getElementsByClassName("category");

 for(var m = 0; m < myNodelist.length; m++) {
     var subText = myNodelist[m].childNodes;
     var len = subText.length;

     for (var jj = 0; jj < len; jj++) {
        if(subText[jj].nodeType === Node.TEXT_NODE) {
             console.log(subText[jj].nodeValue);
             subText[jj].nodeValue = 
             subText[jj].nodeValue.replace(/Mock/,"123");
        }
     }
 }

Currently i am getting the index successfully with the value from the exertion of the highest text appearance in the DOM. Then i am looping through the Nodelist again, evaluating if its a,

Node.TEXT_NODE

https://developer.mozilla.org/de/docs/Web/API/Node/nodeType

Now i only know how to replace the

textNode.value

with another value. What i am really trying to achieve is to get the parentNode of the textNode and add a class to it. If the condition for index (highest appearance) is met. What i found is

Adding a class to a given element. and ParentNode MDN

The problem is i can't really figure out how to access the parentNode out of the second for loop and add a class to the parentNode, so all parents (span tags) that only have the index (text value) get a certain class.

Thanks for help !

3 Answers3

0

What i am really trying to achieve is to get the parentNode of the textNode and add a class to it.

You don't need to find it, you already have myNodelist[m] whose childNodes you were iterating.

If the condition for index (highest appearance) is met.

You have the node-Value with you here subText[jj].nodeValue, and you already have the obj having the number of appearances by the nodeValue

So, simply add this logic

if ( obj[ subText[jj].nodeValue ] == max )
{
  //logic to add the class should be here
  myNodelist[m].classList.add("otherclass");
}
subText[jj].nodeValue = subText[jj].nodeValue.replace(/Mock/,"123");
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
0

You can access to li using parentNode on the myNodelist[m]

var myNodelist = Array.from(document.querySelectorAll(".category"));
var obj = {};

for(var i = 0; i < myNodelist.length; i++){
    //convert array to object with unique elements and number of times 
    //each element is repeated
    var x = myNodelist[i].innerHTML;
    //console.log(x);

    if(!obj[x]){
       obj[x] = 1;
    } else {
       obj[x]++;
    }
 }

 var index = 0;
 var max = 0;

 for(var obIndex in obj) {
    // Traverse the object to get the element
    if(obj[obIndex] > max) {
       max = obj[obIndex];
       index = obIndex.replace(" ", "");
    }
 }

 console.log(index + " is max time repeated: " + max + " times." );

 var v = document.getElementsByClassName("category");

 for(var m = 0; m < myNodelist.length; m++) {
     var subText = myNodelist[m].childNodes;
     var len = subText.length;

     for (var jj = 0; jj < len; jj++) {
        if(subText[jj].nodeType === Node.TEXT_NODE) {
           if (obj[subText[jj].nodeValue] == max) {
              myNodelist[m].parentNode.className += " red";
           }
           console.log(subText[jj].nodeValue);
           subText[jj].nodeValue = 
           subText[jj].nodeValue.replace(/Mock/,"123");
        }
     }
 }
.red {
  color: red;
}
<ul>
    <li class="item">
       <span class="category">
          most occurring text
       </span>
    </li>
    <li class="item">
       <span class="category">
          some text
       </span>
    </li>
    <li class="item">
       <span class="category">
          some text
       </span>
    </li>
    <li class="item">
       <span class="category">
          most occurring text
       </span>
    </li>
    <li class="item">
       <span class="category">
          most occurring text
       </span>
    </li>
 </ul>
aabilio
  • 1,697
  • 12
  • 19
0

To get the parent of a text node just use myTextNode.parentNode and then use classList to add the class to the parent. This could also be achieved using the treewalker api.

function markMostOccurring(parentSelector, markFn) {
  var parent = document.querySelector(parentSelector) || document.body;
  var walker = document.createTreeWalker(parent, NodeFilter.SHOW_TEXT, { 
    acceptNode: node => !!node.nodeValue.trim()
  });
  
  var occurenceMap = {};
  while(walker.nextNode()) {
    var key = walker.currentNode.nodeValue.trim();
    var nodes = occurenceMap[key] = occurenceMap[key] || [];
    nodes.push(walker.currentNode);
  }
  
  var nodes = Object.keys(occurenceMap)
    .sort((a, b) => occurenceMap[b].length - occurenceMap[a].length)
    .map(key => occurenceMap[key])[0]
    .forEach(node => markFn.call(node));
}

markMostOccurring('.container', function() {
  this.parentNode.classList.add('mark');
  this.nodeValue = this.nodeValue.replace('most', 'cat'); 
});
.mark {
  color: red;
}
<ul class="container">
  <li class="item">
    <span class="category">
        most occurring text
    </span>
  </li>
  <li class="item">
    <span class="category">
      some text
    </span>
  </li>
  <li class="item">
    <span class="category">
      some text
    </span>
  </li>
  <li class="item">
    <span class="category">
      most occurring text
    </span>
  </li>
  <li class="item">
    <span class="category">
      most occurring text
    </span>
  </li>
</ul>
cyr_x
  • 13,987
  • 2
  • 32
  • 46