dreamsynk
dreamsynk

Reputation: 71

Add active class to menu on scroll point or id as well as on click

I am trying to get the menu items to get the "active" class not only when they are clicked on but also when scrolled to the id's of #main, #features etc. Right now I have some jquery that adds an active class and removed it from other menu items on click, but as soon as a scroll obviously that menu item stats active, as its only working on clicks and not scroll points.

<ul id="menu-main-menu" class="nav navbar-nav">
  <li class="menu-item"><a title="Home" href="#main">Home</a></li>
  <li class="menu-item"><a title="Features" href="#features">Features</a></li>
  <li class="menu-item"><a title="About" href="#about">About</a></li>
  <li class="menu-item"><a title="Contact us" href="#fill">Contact us</a></li>
</ul>

The theme i bought is using stellar.js and I think this is the js creating scroll points:

jQuery('a[href*=#]:not([href=#])').click(function () {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {

    var target = jQuery(this.hash);
    target = target.length ? target : jQuery('[name=' + this.hash.slice(1) + ']');
    if (target.length) {
        jQuery('html,body').animate({
            scrollTop: target.offset().top - 100
        }, 1000);
         return false;
    }
}
});

I just need this to add an active class to my menu and remove it from other items but also on scroll point or target id. Any help would be much appreciated please :)

Updated code I am playing with, not working properly:

jQuery('a[href*=#]:not([href=#])').click(function () {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {

    var target = jQuery(this.hash);
    target = target.length ? target : jQuery('[name=' + this.hash.slice(1) + ']');
    if (target.length) {
        jQuery('html,body').animate({
            scrollTop: target.offset().top - 100
        }, 1000);

        jQuery(".menu-item a").removeClass("active");

        target.addClass("active");
        target.hasClass("active").find(this).addClass("active");

        return false;
    }
}
});

Upvotes: 0

Views: 3520

Answers (2)

Kolby
Kolby

Reputation: 2865

win.scroll(function(e){
    jQuery.each(items, function(key, value){
        var item = jQuery(value);
        if(win.scrollTop() >= item.offset().top){
            jQuery('.menu-item a.active').removeClass('active');
            var id = item.attr('id');

            jQuery.each(navItems, function(key, value){
                var navItem = jQuery(value);
                if(navItem.attr('href') == '#'+id) navItem.addClass('active');
            });
        }
    });
});

Sorry I misunderstood your question. I think this is what you're looking for: http://jsfiddle.net/pnsxg2zh/

So basically on scroll I get the scroll position of the window, and then use offset().top to find the position of the elements you want to scroll to. I check if the window's scroll position is >= the top of the element, if it is I add the active class to the nav item who has the href equal to the id of that element.

Upvotes: 1

Jimmy Febio
Jimmy Febio

Reputation: 1

so you need to add class "active" when menu-item is clicked and the element (#main and other) is visible on the screen.

to add "active" class on clicked, do this:

jQuery('.menu-item').click(function(){
    jQuery('#menu-main-menu li').removeClass('active');
    jQuery(this).removeClass('menu-item').addClass('menu-item active');
});

to check element visibility please read this post

Check if element is visible after scrolling

Upvotes: 0

Related Questions