How to highlight active links for one-page navigation with JavaScript

One of my clients wanted to highlight the currently active menu items from the navbar as the user scrolls through their one page website sections. I implemented the requested feature and I thought I would share how it was achieved.

Here is a simple demonstration of the mentioned effect.

Notes

  • I’ll not go much into styling the involved elements to keep this tutorial short and precise.
  • We’ll be using jQuery, so this tutorial assumes the library is loaded on your page.

Let’s get started.

First of all, we are going to create a navigation menu, or navbar, it’s going to be in the following format.

<div class="nav-container">
    <div class="nav">
        <a href="#section_1">Features</a>
        <a href="#section_2">Why Us</a>
        <a href="#section_3">About Us</a>
        <a href="#section_4">Team</a>
        <a href="#section_5">Contact</a>
    </div>
</div>

You can obviously use your own navigation, but we’ll keep it simple for this tutorial. Each menu item should be pointing to an existing section with the corresponding ID.

Let’s do the magic.

In your scripts file (.js) , or within the scripts tag of your HTML document, add the following to get started.

$(document).ready(function () {


    // Our code will go here
});

We’ll wrap all out code inside a `ready` function, so that it run once the page is ready for JavaScript code to execute.

To manipulate navigation menu items on scroll we need to listen to scroll event.

$(window).scroll(function (e) {
  // Our logic here
});

Now that we have the scroll listener ready, we need to create the logic to find the section in view and highlight the corresponding menu item.

// Detect how far are we from the top of the page
let windowTop = $(this).scrollTop();
// Loop through every navigation menu item
$('.nav a').each(function (event) {

    // Check for the current navigation item associated section
    // Check how far the associated section is from the top
    // If the associated section is as far as the user have scrolled, add 'active' class to the item.
    if (windowTop >= $($(this).attr('href')).offset().top - 100) {
        // Remove 'active' from previously highlighted menu items
        $('.nav .active').removeClass('active');

        // Highlight the current menu item by adding 'active' class
        $(this).addClass('active');
    }
});

With the code above inside our scroll listener, JavaScript will be able to detect the sections in view and highlight the menu items pointing to them. Don’t forget to add styling to the `active` CSS class to give the highlighted items some special looks.

If you want to view the whole code for this implementation with a little bit of customization added to it, you can find it on Github.