遍历DOM,获取具有最高外观的文本并将类添加到父

时间:2017-10-24 09:01:49

标签: javascript dom traversal nodelist

我正在遍历这个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>

使用以下代码:

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");
        }
     }
 }

目前,我正在使用DOM中最高文本外观的值来成功获取索引。然后我再次循环遍历Nodelist,评估它是否为

  

Node.TEXT_NODE

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

现在我只知道如何更换

  

textNode.value

另一个值。 我真正想要实现的是获取textNode的 parentNode 并向其添加一个类。如果满足索引(最高外观)的条件。我发现的是

Adding a class to a given element.ParentNode MDN

问题是我无法弄清楚如何做到  从 second for loop 中访问parentNode并添加一个类  parentNode,所以所有父项(span标签)只有索引(文本  价值)获得某一类。

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

  

我真正想要实现的是获取的parentNode   textNode并向其添加一个类。

您不需要找到它,您已经有id q1 q2 q3 q4 q5 1 7 4 2 3 5 2 5 7 2 6 1 4 4 7 8 2 3 您正在迭代的子节点。

  

如果满足索引(最高外观)的条件。

您在myNodelist[m]处有 node-Value ,并且subText[jj].nodeValue obj出现的次数>

所以,只需添加此逻辑

即可
nodeValue

答案 1 :(得分:0)

您可以使用parentNode

上的myNodelist[m]访问 li

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>

答案 2 :(得分:0)

要获取文本节点的父节点,只需使用myTextNode.parentNode,然后使用classList将类添加到父节点。这也可以使用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>