Search code examples
scrollnavwp-nav-menu-item

classList is only affect the first li in the ul despect the fact that all the elements where selected


classList is only affect the first li in the ul despect the fact that all the elements where selected.

document.addEventListener("scroll", function() {
  const headerChangejh = document.querySelector(".nav-link");
  if (window.scrollY > 0) {
    headerChangejh.classList.add("scrolledy");
  } else {
    headerChangejh.classList.remove("scrolledy");
  }
})
  .nav-link {
  font-size: 1.2rem;
  font-weight: 800;
  transition: 0.7s ease;
  color: black;
}

.nav-link:hover {
  color: red;
  .nav-link.scrolledy {
    color: #2196f3;
  }
<ul class="nav-menu">
  <li class="nav-item">
    <a href="#" class="nav-link">For Individual</a>
  </li>

  <li class="nav-item">
    <a href="#" class="nav-link">For Companies</a>
  </li>

  <li class="nav-item">
    <a href="#" class="nav-link">App</a>
  </li>

  <li class="nav-item">
    <a href="#" class="nav-link">Jobs</a>
  </li>

  <li class="nav-item">
    <a href="#" class="nav-link">Contact us</a>
  </li>

</ul>

the above code only changes the first li in the ul, while other remain unchange despite the fact that all the elements was selected


Solution

    • I'm unsure what effect you're after, as the current 'scroll' event-listener simply colors all .nav-link elements based on whether or not the window has scrolled - instead of coloring elements based on, say, how far down the page they are or how much the user scrolled-passed, around, or over them. Your question-post does not describe the ultimate effect you're after, so I largely left it as-is.

    • As for bugs-in-your-code:

      • You need to use querySelectorAll, not querySelector, to get all matching elements - using querySelector will return only the first matching element (i.e. your "For Individual" <li>)

        • Also, even if your code used querySelectorAll, your scroll event-listener does not iterate over all matched elements: it just has a single if to add/remove a CSS class-name. I've replaced it with a for(of) loop (which is better than using .forEach because there's no implicit closure) that uses the toggle( className, force ) method, for more succinct code.
      • Your CSS was malformed: you needed to fix it, as below:

        Malformed CSS:

        .nav-link:hover {
          color: red;
         .nav-link.scrolledy {
          color: #2196f3;
        }
        

        Fixed CSS:

        .nav-link:hover {
          color: red;
        }
        .nav-link.scrolledy {
          color: #2196f3;
        }
        
    • Additionally, I made the .nav-link elements bigger so you can better see the transition: to their color property.

    document.addEventListener("scroll", function() {
      const links = document.querySelectorAll(".nav-link");
      for (const l of links) l.classList.toggle('scrolledy', window.scrollY > 0);
    })
    .nav-link {
      font-size: 1.2rem;
      font-weight: 800;
      transition: color 0.7s ease;
      color: black;
      display: block;
      height: 75px;
      background-color: #eee;
      border: 1px solid #ddd;
    }
    
    .nav-link:nth-child(odd) {
      background-color: #fff;
    }
    
    .nav-link:hover {
      color: red;
    }
    
    .nav-link.scrolledy {
      color: #2196f3;
    }
    <ul class="nav-menu">
      <li class="nav-item">
        <a href="#" class="nav-link">For Individual</a>
      </li>
    
      <li class="nav-item">
        <a href="#" class="nav-link">For Companies</a>
      </li>
    
      <li class="nav-item">
        <a href="#" class="nav-link">App</a>
      </li>
    
      <li class="nav-item">
        <a href="#" class="nav-link">Jobs</a>
      </li>
    
      <li class="nav-item">
        <a href="#" class="nav-link">Contact us</a>
      </li>
    
    </ul>