Click here to Skip to main content
15,667,847 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I want to make the links in my navbar have an active class when you scroll into the corresponding section.

The code below was working just fine until I implemented a smooth scroll/parallax library which removes the scroll event.

Here's a codepen. If you uncomment the locomotive portion in the JS, the code no longer works. How can I make it work?

Here's a snippet of the code:

const sections = document.querySelectorAll("section");
const navLinks = document.querySelectorAll("nav a");

window.addEventListener("scroll", function () {
  let navbar = document.querySelector("nav");
  let current = "";
  sections.forEach(function (section) {
    const sectionTop = section.offsetTop;
    const sectionHeight = section.clientHeight;
    if (scrollY >= sectionTop - sectionHeight / 3) {
      current = `#${section.getAttribute("id")}`;
    navLinks.forEach(function (each) {
      // add/remove active class
      if (each.getAttribute("href") == current) {

What I have tried:

I tried making the code work using the wheel event, tried seeing if there was anything similar to scrollY for wheel events but I couldn't find anything.

Any ideas on how I could implement this feature? It can be different from the implementation I had before
Updated 15-Sep-21 23:47pm
Richard Deeming 16-Sep-21 3:48am    
Looks like you've already got your answer on StackOverflow:
javascript - Make navbar link active on wheel event rather than scroll? - Stack Overflow[^]
Fernanda Azevedo 16-Sep-21 5:00am    
No, the answer there doesn't answer my question. As I said, I've already tried wheel event but it doesn't work because I was using "ScrollY" and that doesn't exist in wheel events

1 solution

Try using an IntersectionObserver instead:
const navLinks = document.querySelectorAll("nav a");

const updateNav = (entries, observer) => {
    const matchingIds = entries.filter(e => e.isIntersecting).map(e => `#${}`);
    if (matchingIds.length !== 0) {
        const current = matchingIds[0];
        navLinks.forEach(function(link) {
            if (link.getAttribute("href") == current) {

const options = {
    root: null,
    rootMargin: "0px",
    threshold: 0.66

const observer = new IntersectionObserver(updateNav, options);
document.querySelectorAll("*[data-scroll-section]").forEach(el => observer.observe(el));
Intersection Observer API - Web APIs | MDN[^]
Share this answer

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900