DEV Community

Areeb ur Rub
Areeb ur Rub

Posted on

53 3

Nav-link's to active as you scroll through sections, in 10 Lines of JavaScript;

Buy Me A Coffee

You must have seen single page websites which have different sections displaying different information, and when you scroll down to every section the navbar active link changes.
Nav-bar Demo

You might know that you can add links to each section in a navbar for single page websites by just simply using <a href="#sectionID">Section Name</a> but this doesn't change the style of the nav-links to active.

to change the link style we can simply add a active to the classList of link.

So first we have to check in which section we are in for that we are simple taking every section top offset and when the pages y offset is equal to it we are then taking it's id attribute and adding the active class to it's link

All this is done every time the page is scrolled.

window.onscroll = () => {
  var current = "";

  sections.forEach((section) => {
    const sectionTop = section.offsetTop;
    if (pageYOffset >= sectionTop ) {
      current = section.getAttribute("id"); }
  });

  navLi.forEach((li) => {
    li.classList.remove("active");
    if (li.classList.contains(current)) {
      li.classList.add("active");
    }
  });
};

More things,

if we do it in this way then it will keep the upper section link active until the lower one reach the top so to avoid this we can subtract some numbers so that it don't behave like that.

more things we can do is take the height of Section and use some subtract some of its part from the section top like this pageYOffset >= sectionTop - (sectionHeight /2)

Buy Me A Coffee
Follow Me for more:

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (5)

Collapse
 
xxconcasxx profile image
xXConcasXx

Use

if (li.href.includes(current)) {
li.classList.add('active');
}

instead of

if (li.classList.contains(current)) {
li.classList.add("active");
}

Collapse
 
greggcbs profile image
GreggHume • Edited

Good concept, i wonder if there is a better way to do this other than to forEach all elements twice on every scroll.

Adding a throttle will help. The amount of executions the above is making is a crazy amount per scroll.

*update: i did some performance benchmarks, it looks like using throttle or debounce is less performant than letting the function run on every scroll.

I opened an issue here for informational purposes:
github.com/niksy/throttle-debounce...

Collapse
 
shikarmahmoud profile image
Shikar Mahmoud

Hey there, great tutorial. I tried doing the same thing. For some reason, it's not working the way it's working for you. Very confused!

Collapse
 
lkotan profile image
Lutfi Kotan

Thanks for sharing

Collapse
 
salimkhan0007 profile image
salimKhan0007

Thanks

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay