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.

Changing Active Menu Item on Page Scroll Using jQuery

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

Visit us at InstantShift.com

PSD to HTML


InstantShift

Leave a Comment