简体   繁体   中英

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;
    }
}
});
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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM