Skip to content Skip to sidebar Skip to footer

Vanilla JS Change Active State Of Links When Scrolling Refactoring

I'm trying to ditch jQuery from my upcoming projects. I found a way to create a sticky nav on scroll with pure Vanilla JS, and wanted the links on my navigation to change their act

Solution 1:

You can get all sections and links using document.querySelectorAll(). On scroll iterate the list of section from last to first, until you find one that matches. Then remove the .active class from all links, and add it to the link at the active index.

Note: You should use throttling to prevent the calling of changeLinkState multiple times in a second. Another option is to use the Intersection Observer API.

const links = document.querySelectorAll('.links');
const sections = document.querySelectorAll('section');

function changeLinkState() {
  let index = sections.length;

  while(--index && window.scrollY + 50 < sections[index].offsetTop) {}
  
  links.forEach((link) => link.classList.remove('active'));
  links[index].classList.add('active');
}

changeLinkState();
window.addEventListener('scroll', changeLinkState);
nav {
  position: fixed;
  top: 0;
  right: 0;
  width: 10em;
}

section {
  height: 100vh;
  margin: 1em 0;
  background: gold;
}

.active {
  background: silver;
}
<nav>
  <ul>
    <li id="linkTop" class="links">
      <a href="#top">Home</a>
    </li>
    <li id="linkAbout" class="links">
      <a href="#about">About Us</a>
    </li>
    <li id="linkServices" class="links">
      <a href="#services">Services</a>
    </li>
    <li id="linkClients" class="links">
      <a href="#clients">Clients</a>
    </li>
    <li id="linkContact" class="links">
      <a href="#contact">Contact</a>
    </li>
  </ul>
</nav>

<section>
  Home
</section>

<section>
  About Us
</section>

<section>
  Services
</section>

<section>
  Clients
</section>

<section>
  Contact
</section>

Solution 2:

There can be more than one ways of highlighting the Nav. One way of implementing this feature is as follow-

We will apply "active" class to an active Nav link and add some css for this class to highlight it.

Here are the steps how you can apply "active" class to a proper Nav link:

STEP 1-

Add a class to every Nav links same as the id of corresponding section while creating your Nav bar.

For example, the Nav link corresponding to a section having id="section1" will have its class set to section1 ( i.e class="section1")

STEP 2-

On Scroll event in the browser, iterate through every section and check if it is in the view-port (getBoundingClientRect()) .

If a section is in the viewport, make this as well as the corresponding Nav link active as follow-

if (section is in the viewport) {
    // 1. Add "your-active-class" to the current section
    // 2. Add "active" class to the Nav link which have a class same as id of the current section
    } else {
     // 1. Remove "your-active-class" from the current section.
 // 2. Remove "active" class from the Nav link which have a class same as id of current section
    }

STEP 3-

In you css file, write styles for class "active" and "your-active-class" so that the Nav link and section can be highlighted using different text or background colors.


Post a Comment for "Vanilla JS Change Active State Of Links When Scrolling Refactoring"