Home > Software design >  How to generate the same class name for UL element under LI using JavaScript?
How to generate the same class name for UL element under LI using JavaScript?

Time:09-26

I have tried to generate/create the class name dynamically in the ul element and I have got the expected result successfully which can be seen in the console of the snippet for reference.

But I'm trying to create the same class name if the ul is generated under a li element. For example, there is a li element with the class name "a" and if we create multiple ul elements under the same li element the class name of ul should be the same as below but instead of that the class gets counted.

The result I need:

<li class="a">
    <a href="/">First</a>
    <ul class="main-nav-list">
        <li class="b">
            <a href="/">Type of menu</a>
            <ul class="main-nav-list ul-1"> //The ul-1 should be static (even after dyanmic class generated) to the next ul li example if ul-1 one come the next li with ul should also have the same class ul-1
                <li class="c"><a href="/">Summer</a></li>
            </ul> 
        </li>
        <li class="b">
            <a href="/">Type of menu</a>
            <ul class="main-nav-list ul-1">
                <li class="c"><a href="/">Summer</a></li>
            </ul>
        </li>

The code I have tried so far

var ul = document.querySelectorAll(".main-nav ul");

ul.forEach((each, i) => {
    each.classList.add("ul-"   i);
    console.log(each)
});
<nav class="main-nav">
  
  <ul class="main-nav-list">
    <li class="a">
      <a href="/">First</a>
      
      <ul class="main-nav-list"> 
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>
    
    </li>
  </ul>

</nav>
enter image description here

If First Ul has class ul-0 then the next ul should also have ul-0 as a class. Any Help will be appreciated !!

CodePudding user response:

You have to select each li and for each of them iterate over its uls, then add any class you want to them.

// selecting li's of main ul in the page
var lis = document.querySelectorAll(".main-nav>ul>li");

lis.forEach((each) => {

    // selecting all uls inside each li
    let innerUls = each.querySelectorAll(`:scope>ul`)


    // adding class name to each ul
    innerUls.forEach((itm, index) => {
      itm.classList.add("ul-"   index);
    })
});
<nav class="main-nav">
  
  <ul class="main-nav-list">
    <li class="a">
      <a href="/">First</a>
      
      <ul class="main-nav-list"> 
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>
    
    </li>
    
    <li class="a">
      <a href="/">Second</a>
      
      <ul class="main-nav-list"> 
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>
      
      <ul class="main-nav-list"> 
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>
      
      <ul class="main-nav-list"> 
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>
    </li>
  </ul>
</nav>


UPDATE

Adding class to uls recursively

let classNames = ['a', 'b', 'c', 'd', 'e'];
function addClassToUls(ul, level) {
  var lis = ul.querySelectorAll(':scope>li');
  lis.forEach((each) => {

    // selecting all uls inside each li
    let innerUls = each.querySelectorAll(`:scope>ul`)


    // adding class name to each ul
    innerUls.forEach((itm, index) => {
      itm.classList.add(`ul-${level}-${classNames[index]}`);
      addClassToUls(itm, level 1);
    })
  })
}

let mainUls = document.querySelectorAll(".main-nav>ul");

mainUls.forEach(ul => addClassToUls(ul, 1))
<nav class="main-nav">

  <ul class="main-nav-list">
    <li class="a">
      <a href="/">First</a>

      <ul class="main-nav-list">
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>

    </li>

    <li class="a">
      <a href="/">Second</a>

      <ul class="main-nav-list">
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>

      <ul class="main-nav-list">
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>

      <ul class="main-nav-list">
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">// In my case, if the class is ul-1 then next li ul is generating as ul-2 but i want it to be same in the both the li component
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
        <li class="b">
          <a href="/">Type of menu</a>

          <ul class="main-nav-list">
            <li class="c"><a href="/">Summer</a></li>
          </ul>

        </li>
      </ul>
    </li>
  </ul>
</nav>

  • Related