Changing Active Menu Item on Page Scroll Using jQuery

This tutorial will teach you how to change the active menu item on page scroll without using any special js files or plug-in.

In this demo we’ll use simple jQuery functions to accomplish our goal.

Expected Output:

On page scroll event, the selected (active) menu item will be changed according to the current section being viewed. It will also happen if user clicks on any of the menu item link. This type of implementation is good for single page websites having fixed menu bar. Let’s get started.

Live Demo

First Step: Creating the Markup

The markup is very simple and easy. We are going to create simple navigation bar with few menu items as we have on www.instantshift.com. It has few items like Home, Web Design, CSS, Tools, Tutorials etc. The Page will have various text content blocks. Here is how the Markup looks.

<div id="maindiv">
    <div class="container clear">
        <div id="sidebar">
            <div id="checkdiv"></div>
            <nav class="">
                <ul>
                    <li><a href="#home" class="active">Home</a></li>
                    <li><a href="#webdesign">Web Design</a></li>
                    <li><a href="#css">CSS</a></li>
                    <li><a href="#tools">Tools</a></li>
                    <li><a href="#tutorials">Tutorials</a></li>
                </ul>
            </nav>
        </div> <!-- sidebar div end -->
        <div id="content">
            <section id="home">
                <h1>Home</h1>
                <p><!-- Home Content Goes Here --></p>
            </section>
            <section id="webdesign">
                <h1>Web Design</h1>
                <p><!-- Web Design Content Goes Here --></p>
            </section>
            <section id="css">
                <h1>CSS</h1>
                <p><!-- CSS Content Goes Here --></p>
            </section>
            <section id="tools">
                <h1>Tools</h1>
                <p><!-- Tools Content Goes Here --> </p>
            </section>
            <section id="tutorials">
                <h1>Tutorials</h1>
                <p><!-- Tutorials Content Goes Here --></p>
            </section>
        </div> <!-- contain div end -->
    </div> <!-- container div end -->
</div><!-- maindiv end -->

Our Html markup is ready now it’s time to add some CSS style.

Step Two : Adding CSS classes.

body{
      background-color:#520000;font-size:17px;
}

#maindiv{
      background:#F4F3E8 url(images/page_bg.png);
}

#title h1 {
     text-align: right;font-weight: bold;font-size: 25px;margin: 0;color:#fff;
}

.container {
     width: 1000px;margin: 0 auto;padding: 38px 0;
}

#wrapper{ 
     margin:0px auto;
}

#sidebar {
    width:250px;float:left;
}

#content {
   width:720px;float:right;padding-left:12px;
}

#title {
   width: 900px;height: 60px;float: right;
}

.clear:after {
   visibility: hidden;display: block;content: "";clear: both;height: 0;
}

nav {
  width:213px;background-color:#030000;border: 2px solid #4F4D4D;padding:0 12px;
}

nav.stickydiv {
   position: fixed;top: 0;z-index: 10000;margin-top:12px;
}

nav ul {
list-style-type:none;margin:0;padding:0;
}

nav li {
padding:5px 10px;
}

nav li a {
color:#fff;font-weight:700;line-height: 25px;
}

a{
text-decoration:none;
}

.active {
color: #F99;text-decoration: none;
}

p{
font-family:Verdana,Arial,Helvetica,sans-serif;
}

footer p{
  color:#fff;
}

Step Three : Checking the playground “jQuery”.

First of all we make sure that on click of the menu links, corresponding div should be scrolled up. As you can see in the below code, on click of menu item link we are removing the “active” class of current selected menu item and adding the active class to the clicked item link.

Then we are getting the ID of the clicked element. this.hash will return “#foo” which is ID selector. Hence $(this.hash) is the same as $(“#foo”) and it will select the element with ID foo.

$('a[href^="#"]').on('click', function (e) {
        e.preventDefault();
        $(document).off("scroll");
        
        $('a').each(function () {
            $(this).removeClass('active');
        })
        $(this).addClass('active');
         var target = this.hash,
         menu = target;
        $target = $(target);
              
       $('html, body').stop().animate({
            'scrollTop': $target.offset().top+2
        }, 600, 'swing', function () {
            window.location.hash = target;
            $(document).on("scroll", onScroll);
        });
    });

On scroll event we are checking the position of elements against the scrolling amount as well as the sum of their height and position. On this basis we are adding and removing the active class of the menu items.

function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#sidebar a').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
            $('#sidebar ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
}

and last on page scroll event we are checking if the sidebar will be sticky or not.

$(window).scroll(function(){
        // the "12" should equal the margin-top value for nav.stickydiv
        var window_top = $(window).scrollTop() + 12; 
        var div_top = $('#checkdiv').offset().top;
            if (window_top >= div_top) {
                $('nav').addClass('stickydiv');
            } else {
                $('nav').removeClass('stickydiv');
            }
 });

Here is complete script.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$(window).scroll(function(){
        var window_top = $(window).scrollTop() + 12; 
       // the "12" should equal the margin-top value for nav.stickydiv
        var div_top = $('#checkdiv').offset().top;
        if (window_top >= div_top) {
                $('nav').addClass('stickydiv');
            } else {
                $('nav').removeClass('stickydiv');
            }
    });  

  $(document).on("scroll", onScroll);

$('a[href^="#"]').on('click', function (e) {
      e.preventDefault();
        $(document).off("scroll");
         $('a').each(function () {
            $(this).removeClass('active');
        })
        $(this).addClass('active');
         var target = this.hash,
         menu = target;
         $target = $(target);
       $('html, body').stop().animate({
            'scrollTop': $target.offset().top+2
        }, 600, 'swing', function () {
            window.location.hash = target;
            $(document).on("scroll", onScroll);
        });
    });
});

function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#sidebar a').each(function () {
        var currLink = $(this);
       var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
            $('#sidebar ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
}
</script>

That’s it, it’s easy right? Enjoy! Don’t forget to check out the demo.

Live Demo and Source Code

jQuery Action Menu

Here you can see this action menu in live action. Also, you can download the source files so you can edit and directly use them in what-so-ever you like.

Live Demo Download Source Code

Like it? Share it.

9 Comments

  1. I really appreciate for this jquery code. It’s amazing post you share with us. Thanks

  2. Hi, patel
    This is very good post for beginner, developer thanks for sharing this information.

  3. Because of a fantastic hard work within posting the information you have. One can are more educational because this specific. There are lots of issues I could understand merely following examining your own wonderful Information.

  4. Great example! Thanks very much 🙂

  5. Scrolling is not working in IE.It is working only in chrome.
    Any ideas or suggestions.
    Thanks in advance

  6. Hello, nice tutorial!

    I just want to know… is it possible to add a class “active” to the Div/Section ID where the link is pointing ?

    Thanks for your help 🙂

  7. This is really nice and simple tutorial, thanks to share it with us 🙂 I also wrote a tutorial which highlight the active page, hope you also find it helpful.
    allphptricks.com/jquery-automatically-highlight-current-page/

  8. Thanks . Good code ! That great !

Leave a Comment Yourself

Your email address will not be published. Required fields are marked *