Search code examples
jquerycsswordpresssubmenu

How to add “active” class to current menu item in WordPress


I have a WordPress based website, and my theme highlights the current menu item by adding "current-menu-item" class to it.

The thing is that I have a menu item with 3 submenu items and all of them point to the same page with different container ids (their href contains container Id), hence all of them are highlighted.

How can I highlight only the menu item which's href points to the currently viewed container?

<ul>
<li><ahref="URL/who-we-are/"><span>WhoWeAre</span></a>
<ul>
    <li id="first"><ahref="URL/who-we-are/#wherewework"><span>WhereWeWork</span></a></li>
    <li id="second"><ahref="URL/who-we-are/#whatwebelieve"><span>WhatWeBelieve</span></a></li>
    <li id="third"><ahref="URL/who-we-are/#ourpartners"><span>OurPartners</span></a></li>
</ul>
</li>
<li><ahref="#"><span>GetInvolved</span></a>
<ul>
    <li><ahref="URL/vacancies/"><span>Vacancies</span></a></li>
    <li><ahref="URL/Become-Active/"><span>BecomeActive</span></a></li>
</ul>
</li>
<li><ahref="URL/contactus/"><span>ContactUs</span></a></li>
</ul>

I have tried this answer by inserting the following after tag:

function onVisibilityChange(el, callback) {
    var old_visible;
    return function () {
        var visible = isElementInViewport(el);
        if (visible != old_visible) {
            old_visible = visible;
            if (typeof callback == 'function') {
                callback();
            }
        }
    }
}

var handler = onVisibilityChange(#whatwebelieve, function() {
    $( "#second" ).removeClass( "current-menu-item" )
});


//jQuery
$(window).on('DOMContentLoaded load resize scroll', handler);

Solution

  • It a simple scrollspy.

    // Cache selectors
    var lastId,
      topMenu = $("#top-menu"),
      topMenuHeight = topMenu.outerHeight() + 15,
      // All list items
      menuItems = topMenu.find("a"),
      // Anchors corresponding to menu items
      scrollItems = menuItems.map(function() {
        var item = $($(this).attr("href"));
        if (item.length) {
          return item;
        }
      });
    
    // Bind click handler to menu items
    // so we can get a fancy scroll animation
    menuItems.click(function(e) {
      var href = $(this).attr("href"),
        offsetTop = href === "#" ? 0 : $(href).offset().top - topMenuHeight + 1;
      $('html, body').stop().animate({
        scrollTop: offsetTop
      }, 300);
      e.preventDefault();
    });
    
    // Bind to scroll
    $(window).scroll(function() {
      // Get container scroll position
      var fromTop = $(this).scrollTop() + topMenuHeight;
    
      // Get id of current scroll item
      var cur = scrollItems.map(function() {
        if ($(this).offset().top < fromTop)
          return this;
      });
      // Get the id of the current element
      cur = cur[cur.length - 1];
      var id = cur && cur.length ? cur[0].id : "";
    
      if (lastId !== id) {
        lastId = id;
        // Set/remove active class
        menuItems
          .parent().removeClass("active")
          .end().filter("[href='#" + id + "']").parent().addClass("active");
      }
    });
    body {
      height: 6000px;
      font-family: Helvetica, Arial;
    }
    
    #top-menu {
      position: fixed;
      z-index: 1;
      background: white;
      left: 0;
      right: 0;
      top: 0;
    }
    
    #top-menu li {
      float: left;
    }
    
    #top-menu a {
      display: block;
      padding: 5px 25px 7px 25px;
      width: 4em;
      text-align: center;
      -webkit-transition: .5s all ease-out;
      -moz-transition: .5s all ease-out;
      transition: .5s all ease-out;
      border-top: 3px solid white;
      color: #aaa;
      text-decoration: none;
    }
    
    #top-menu a:hover {
      color: #000;
    }
    
    #top-menu li.active a {
      border-top: 3px solid #333;
      color: #333;
    }
    
    #foo {
      position: absolute;
      top: 400px;
    }
    
    #bar {
      position: absolute;
      top: 800px;
    }
    
    #baz {
      position: absolute;
      top: 1200px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <ul id="top-menu">
      <li class="active">
        <a href="#">Top</a>
      </li>
      <li>
        <a href="#foo">Foo</a>
      </li>
      <li>
        <a href="#bar">Bar</a>
      </li>
      <li>
        <a href="#baz">Baz</a>
      </li>
    </ul>
    
    <a id="foo">Foo</a>
    
    
    <a id="bar">Bar</a>
    
    
    <a id="baz">Baz</a>