Home > Net >  How to toggle a class through a Pure JavaScript
How to toggle a class through a Pure JavaScript

Time:08-01

I'm trying to toggle a class on a li tag. It adds and removes the class from one element to another but not when I try to re-click a li with the class (active). What am I missing? Tried changing .classList.add to .classList.toggle but that didn't work.

(function(){
    
    let dropDowns = Array.from(document.querySelectorAll('.template-nav > li'));
    
        const handleClick = (e) => {
            dropDowns.forEach(node => {
                node.classList.remove('active');
            });
            e.currentTarget.classList.add('active');
    
        }
    
        dropDowns.forEach(node => {
            node.addEventListener('click', handleClick)
        });
})();

See my work here: https://jsfiddle.net/m5y46qv2/2/

CodePudding user response:

At the moment you always remove the class from all nodes and then add the class to the click target. So, when you click the li with the class, you remove the class and then add it again. To prevent that, you need to not add the class again, if the node already had the class, when clicking.

For example:

(function(){

let dropDowns = Array.from(document.querySelectorAll('.template-nav > li'));

    const handleClick = (e) => {
        let clickedNodeIsActive = e.currentTarget.classList.contains('active')
        dropDowns.forEach(node => {
            node.classList.remove('active');
        });
        if (!clickedNodeIsActive) {
            e.currentTarget.classList.add('active');
        }

    }

    dropDowns.forEach(node => {
        node.addEventListener('click', handleClick)
    });
})();

CodePudding user response:

I think your code is fine, you are just missing a small check to see if the clicked item already has the active class which means that you've clicked the same element. Something like this:

const handleClick = (e) => {
  if (e.target.classList.contains('active')) {
      e.target.classList.remove('active');
  } else {
    dropDowns.forEach(node => {
      node.classList.remove('active');
    });

    e.currentTarget.classList.add('active');
  }
}
  • Related