Search code examples
javascripthtmlonclickclassname

Switching classes onClick toggle


I am learning by doing and have hit a road block while developing a website. I have a menu with 4 options, there is an active state and off state in css as well as the first option is active by default. When clicking any option it toggles it to the active state but does not change the previous one to the off state.

Code:

function myFunc(e) {
  if (e.className == 'channel') {
    e.className = 'channel active';
  } else {
    e.className = 'channel';
  }
}
<li id="test" class="channel active" data-v-a3c933a2="" onclick="openPlayer('option1'); myFunc(this)">
  <div class="status offline" data-v-a3c933a2="">Offline <span class="viewers" data-v-a3c933a2="">0</span>
  </div><a rel="nofollow" href="javascript:void" class="button" style="border-bottom-color:#ee4b23;" data-v-a3c933a2="">Option1</a>
</li>
<li id="test" class="channel" data-v-a3c933a2="" onclick="openPlayer('option2'); myFunc(this)">
  <div class="status offline" data-v-a3c933a2="">Offline <span class="viewers" data-v-a3c933a2="">0</span>
  </div><a rel="nofollow" href="javascript:void" class="button" style="border-bottom-color:#ee4b23;" data-v-a3c933a2="">Option2</a>
</li>
<li id="test" class="channel" data-v-a3c933a2="" onclick="openPlayer('option3'); myFunc(this)">
  <div class="status offline" data-v-a3c933a2="">Offline <span class="viewers" data-v-a3c933a2="">0</span>
  </div><a rel="nofollow" href="javascript:void" class="button" style="border-bottom-color:#ee4b23;" data-v-a3c933a2="">Option3</a>
</li>
<li id="test" class="channel" data-v-a3c933a2="" onclick="openPlayer('option4'); myFunc(this)">
  <div class="status offline" data-v-a3c933a2="">Offline <span class="viewers" data-v-a3c933a2="">0</span>
  </div><a rel="nofollow" href="javascript:void" class="button" style="border-bottom-color:#ee4b23;" data-v-a3c933a2="">Option4</a>
</li>

How do I go about having all nonactive options actually display in the off state instead of just toggling per-click?

Thank you for your time!


Solution

  • Your code doesn't remove the active class from the other LIs. Loop through the LIs and remove the active class. As for the LI that is clicked, check if it's active. If it is, remove the class. If it's not, add the class.

    function myFunc(e) {
      document.querySelectorAll('li').forEach((li) => {
        // Check if the clicked li has the class 'active'. If it doesn't,
        // add the 'active' class.
        if (e === li && !e.classList.contains('active')) {
          li.classList.add('active');
        } else { // Just remove the 'active' class from each li.
          li.classList.remove('active');
        }
      });
    }
    

    function myFunc(e) {
      document.querySelectorAll('li').forEach((li) => {
        // Check if the clicked li has the class 'active'. If it doesn't,
        // add the 'active' class.
        if (e === li && !e.classList.contains('active')) {
          li.classList.add('active');
        } else { // Just remove the 'active' class from each li.
          li.classList.remove('active');
        }
      });
    }
    
    const lis = Array.from(document.getElementsByTagName('li'));
    
    lis.forEach((li) => {
    	li.addEventListener('click', myFunc.bind(null, li));
    });
    * {
      margin: 0;
      padding: 0;
    }
    
    body {
      font: normal 14px/1.8 sans-serif;
    }
    
    ul {
      list-style: none;
    }
    
    li {
      cursor: pointer;
      display: inline-block;
      padding: 10px;
    }
    
    a {
      color: #666;
      text-decoration: none;
    }
    
    .active {
      background: #999;
    }
    
    .active a {
      color: #fff;
    }
    <ul>
      <li>
        <a href="#">Option 1</a>
      </li>
      <li>
        <a href="#">Option 2</a>
      </li>
      <li>
        <a href="#">Option 3</a>
      </li>
      <li>
        <a href="#">Option 4</a>
      </li>
    </ul>