Search code examples
javascriptnodelist

Add and remove classes from Node in Javascript


I have a slider in my page and slider's indicators are dynamic, It bases on slider's elements' number and width of body.

My code block is:

function setIndicators(){
  const indicator = document.createElement("div");
  indicator.className = "indicator active";
  indicatorContainer.innerHTML = "";
  for(let i = 0;i <= maxIndex; i++){
    indicatorContainer.appendChild(indicator.cloneNode(true));
  }
  updateIndicators();
}

which is working fine. But I want to show active indicator but I cannot manipulate elements' classes.

I tried this:

function updateIndicators(index) {
  indicators.forEach((indicator) => {
    indicator.classList.remove("active");
  });
  let newActiveIndicator = indicators[index];
  newActiveIndicator.classList.add("active");
}

And I am not able to reach every indicators using index or anything I know/find. Also, it seems like NodeList not a HTML element.

Other things you may need:

const indicatorContainer = document.querySelector(".container-indicators");
const indicators = document.querySelectorAll(".indicator"); 
let maxScrollX = slider.scrollWidth - body.offsetWidth;
let baseSliderWidth = slider.offsetWidth;
let maxIndex = Math.ceil(maxScrollX / baseSliderWidth);

Solution

  • A better one I would suggest using the indicators in a different way. Since your HTML isn't shared, I have to assume a few things:

    function clearAll() {
      const activeOnes = document.querySelectorAll(".active");
      activeOnes.forEach(function(activeOne) {
        activeOne.classList.remove("active");
      });
    }
    
    function chooseOne(index) {
      clearAll();
      const indicators = document.querySelectorAll(".indicator");
      indicators[index].classList.add("active");
    }
    * {
      font-family: 'Operator Mono', consolas, monospace;
    }
    
    .indicators {
      border: 2px solid #ccc;
      display: inline-block;
      width: auto;
      margin: 15px;
    }
    
    .indicators .indicator {
      padding: 15px;
      line-height: 1;
      background-color: #fff;
      flex-grow: 1;
      text-align: center;
      display: inline-block;
    }
    
    .indicator.active {
      background-color: #f90;
    }
    <div class="indicators"><div class="indicator">I1</div><div class="indicator">I2</div><div class="indicator">I3</div><div class="indicator">I4</div><div class="indicator">I5</div></div>
    <button onclick="chooseOne(2); return false">Select I3</button>
    <button onclick="chooseOne(3); return false">Select I4</button>

    I would have done this differently this way.

    Preview

    preview