Exploring the document object model, identifying the most frequently occurring text, and applying a class to the element's parent

I have been navigating through this HTML structure:

     <ul>
        <li class="item">
           <span class="category">
              most frequent 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 frequent text
           </span>
        </li>
        <li class="item">
           <span class="category">
              most frequent text
           </span>
        </li>
     </ul>

Using the following JavaScript 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 successfully retrieving the index along with the highest occurrence of a specific text in the HTML structure. After that, I iterate through the NodeList again, checking if it's a,

Node.TEXT_NODE

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

Right now, I can only replace the

textNode.value

with a different value. What I really want to achieve is to identify the parentNode of the textNode and apply a class to it if the condition for the index (highest occurrence) is satisfied. I came across

Adding a class to a given element. and ParentNode MDN

The issue I'm facing is determining how to access the parentNode outside the second loop and add a class to the parentNode so all parent elements (span tags) containing only the index (text value) receive a specific class.

Thank you for your assistance!

Answer №1

You have the ability to retrieve li by utilizing parentNode on the myNodelist[m]

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

for(var i = 0; i < myNodelist.length; i++){
    //transform array into object with unique elements and their frequencies 
    var x = myNodelist[i].innerHTML;

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

 var index = 0;
 var max = 0;

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

 console.log(index + " is the most frequently repeated item: " + 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 recurring 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>

Answer №2

My main goal is to identify the parentNode of a textNode and apply a specific class to it.

No need to search for it, as you already have myNodelist[m], which contains the childNodes you were looping through.

If the condition for the highest index appearance is satisfied.

You can access the node-Value here: subText[jj].nodeValue, and know the number of times this value appears thanks to the obj.

Therefore, you can implement the following logic:

if ( obj[ subText[jj].nodeValue ] == max )
{
  // Implementation for adding the class should be inserted here
  myNodelist[m].classList.add("otherclass");
}
subText[jj].nodeValue = subText[jj].nodeValue.replace(/Mock/,"123");

Answer №3

If you want to find the parent of a text node, you can simply use myTextNode.parentNode and then utilize classList to add a class to the parent element. Another method to achieve this is by using the treewalker api.

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

modifyParentNode('.container', function() {
  this.parentNode.classList.add('modified');
  this.nodeValue = this.nodeValue.replace('most', 'cat'); 
});
.modified {
  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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The server is failing to provide the requested data in JSON format

I am struggling with making a simple API call using Node.js as the backend and React in the frontend. My Node.js file is not returning data in JSON format, and I'm unsure of the reason behind this issue. I need assistance with two main things: Why is ...

Problems Arising from the Content Menu and Tab Opening Features of a Chrome Extension

I am encountering an issue with the code below not displaying the context menu when text is selected on the webpage. Currently, when I select text, the context menu fails to appear. Code function getword(info,tab) { if (info.menuItemId == "google") ...

.class selector malfunctioning

I'm currently developing a card game system where players can select a card by clicking on it and then choose where to place it. However, I've encountered an issue where nothing happens when the player clicks on the target place. Here is the li ...

Issue with parsing JSON data for heatmap in Mapbox

Here's the code I'm using: heat = L.heatLayer([], { maxZoom: 12 }).addTo(map); $.getJSON("js/example-single.geojson", function(data) { var geojsosn = L.geoJson(data, { onEachFeature: function (feature, layer) { console.log(f ...

What are the implications of a project containing nested node_modules directories?

We are currently in the process of dividing our project into "sub modules" within a single repository. Our goal is to maintain aspects such as webpack configurations and express server globally, with a structure similar to the following: package.json serv ...

Troubleshooting compatibility issues between Sailsjs Services and TypeScript in Vscode

Having an issue with TypeScript in a Sails.js application. I am utilizing TypeScript to write my controller and attempting to use Sails.js services within the controllers. However, I encounter a syntax error in VSCODE. Below is the code snippet from MyCo ...

Fixing issues with Ajax calls in Internet Explorer versions 7 and 8

Here is the Javascript code I have written: $("#login").click(function(){ username=$("#user_name").val(); password=$("#password").val(); $.ajax({ type: "POST", url: "login.php", data: "username="+username+"&passw ...

What is the best way to instruct jQuery to disregard an empty server response?

After examining this piece of code: $.ajax({ type: "POST", url: theRightUrl, data: whatToPost, logFunction: whatever, suppressSuccessLogging: !0, dataType: "html" }); I encountered an issue where Firefox displays a "no element ...

Issue with jQuery.parseJSON causing empty data structure to return

I am facing a puzzling problem with manipulating data in JavaScript. The code snippet I am using in JavaScript is to fetch data from a PHP/MySQL source. var _response = jQuery.ajax({ url: "../data", async: false, type: "post", data: oPara ...

What could be the reason for my user input not being captured and saved as variable data on the HTML webpage?

Here is the code I am working with: var g = document.getElementById("al").value; function start() { document.getElementById("test2").innerHTML = typeof(g) + parseFloat(g); } <p id="test2">Output will be displayed here:</p> <form> ...

Increment and decrement the like count on fa-heart multiple times

Is there a way to increment the count of a fa-heart value on click and decrement it on the second click? The issue I'm facing is that I have multiple fa-heart elements on the same page, making it challenging to increment or decrement the clicked fa-h ...

Troubleshooting CSS override issues when swapping components in ReactJS

Access.js import React from 'react' export default class Access extends React.Component { componentWillMount(){ import ('./styles/access_page.css'); } .... <Link to="/new-account">Sign Up</Link> } Cr ...

Showing exclusively JavaScript data in a select element

I am struggling with getting a select tag to display only JavaScript values. Here is the code snippet: <select id="pname"> <option>som data</option> </select> After running a JavaScript function, I want to update the select ta ...

The serialize() method in Ajax is not capturing all the data fields from an HTML form

Attempting to use the jQuery get() method to send form data from my website, I encountered an issue where only a few of the field data were actually transmitted to the server upon form submission. The Form: <form class="form-horizontal" id="addpost" ...

What are the factors that lead to the rendering of an Angular component?

Efficiency is key in maximizing performance with single page applications. Take, for example, React, where any change in state or props within a component triggers a re-execution, re-evaluation, and ultimately, a re-rendering of that component. With that ...

Error Alert: The function findByID is not recognized in this context (Node.js)

I currently have two distinct directories. /controller/anbieter.js function getAnbieterById(req, res) { var userid = parseInt(req.params.id); let anbieter = Anbieter.findById(userid); res.send(anbieter); }; /model/anbieter.js ...

Change the hover effects on the desktop to be more mobile-friendly

In my desktop version, I have implemented some code that enables hovering over a button to display additional information or text. How can I modify this for mobile so that nothing happens when the button is tapped on? .credit:hover .credit-text, .credit- ...

Is there a tool available that can convert the string "foo:blah" into JSON format?

My goal is to transform a human-readable list like the following: Enabled: Yes Server: example.com Port: 8080 Authenticated Proxy Enabled: 1 ... into a sanitized JSON object as shown below: { "Enabled": "Yes", "Server": "example.com", "Port" ...

Guide to adding information to an Excel sheet using JavaScript

I am encountering an issue with writing data into an xls sheet in the correct format. Please refer to the image below for the problem: View my xls sheet Here is the code snippet causing the problem: var readString = ''; readString = "Nam ...

The Object.keys function requires either an assignment or function call, but instead, an expression without being used was encountered, resulting in

Struggling with creating an HTML table using multiple JavaScript methods in ReactJS. Utilizing Object.keys to extract data from objects, facing issues rendering the thead th's and tbody tr's and td's without encountering the error message &a ...