Alex Zahir
Alex Zahir

Reputation: 969

jQuery smooth scrolling, add a class of active to anchor when the page is scrolled to the respective section

I am using smooth scroll functionality on my page for internal links. I am using something as follows: (note: the menu will be fixed on top of the page and each a tag will be used to jump to that section of the current page)

<ul class="nav navbar-nav">
   <li><a href="#home">Home</a></li>
   <li><a href="#about">About</a></li>
   <li><a href="#mission">Our Mission</a></li>
   <li><a href="#contact">Contact Us</a></li>
</ul>
....
<section id="home"><!-- content goes here --></section>
..
<section id="about"><!-- content goes here --></section>
..
<section id="mission"><!-- content goes here --></section>
..
<section id="contact"><!-- content goes here --></section>
..

I am using the following jQuery script to implement the smooth scroll effect:

      $(function() {
          $('a[href*=#]:not([href=#])').click(function() {
            if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
              var target = $(this.hash);
              target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
              if (target.length) {
                $('html,body').animate({
                  scrollTop: target.offset().top
                }, 1000);
                return false;
              }
            }
          });
        });

This works fine, but what I want is for a way that when the user scrolls to say, section#mission i want a class of active added to the a href="#mission". Using this class i would specify styles(background color) for the current active anchor tag.

I want to know how this can be done? I would prefer a jQuery approach.

Thank you for your time.

Made a Fiddle here with which you can work on easily:
https://jsfiddle.net/umehyrza/

Upvotes: 0

Views: 8863

Answers (3)

Mohamed-Yousef
Mohamed-Yousef

Reputation: 24001

you need window scroll event to do that

$(document).ready(function(){
    $(window).scroll(function(){
        var WindowTop = $(this).scrollTop();
        $('section').each(function(i){
            if(WindowTop > $(this).offset().top - 50&& 
               WindowTop < $(this).offset().top + $(this).outerHeight(true)
              ){
                $('.nav > li > a').removeClass('newClass');
                $('.nav li').eq(i).find('a').addClass('newClass');
            }
        });
    });
});

Working Demo

Upvotes: 2

Jacques Marais
Jacques Marais

Reputation: 2756

Try the following:

$(function() {
    $('a[href*=#]:not([href=#])').click(function() {
        if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
            var target = $(this.hash);
            target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
            if (target.length) {
                $('html,body').animate({
                    scrollTop: target.offset().top
                }, 1000);
                $(".nav > li > a").removeClass("newClass");
                $(this).addClass("newClass");
                return false;
            }
        }
    });
    $(window).scroll(function(){
        $("section").each(function(){
            if(ScrollView($(this))){
                var id = $(this).attr("id");
                $(".nav > li > a").removeClass("newClass");
                $(".nav > li > a[href='#" + id + "']").addClass("newClass");
            }
        });
    });
    function ScrollView(element){
        var win = $(window);
        var winTop = win.scrollTop();
        var winBottom = winTop + win.height();
        var elementTop = element.offset().top;
        var elementBottom = elementTop + element.height();

        if((elementBottom <= winBottom) && (elementTop >= winTop)){
            return true;
        }
        return false;
    }
});

JSFiddle.

Upvotes: 3

Praveen Kumar Purushothaman
Praveen Kumar Purushothaman

Reputation: 167172

Use :target:

section:target {background: #99f;}

And don't forget to add that to the location.

location.hash = id;

The script for you:

if (target.length) {
  $('html,body').animate({
    scrollTop: target.offset().top
  }, 1000);
  location.hash = target;
  return false;
}

Upvotes: 3

Related Questions