Search code examples
javascripthtmljquerydomnav

Read location in DOM (webpage) and change navmenu classes accordingly


I have a nav menu that links to certain parts of the page. I want to write some JS so that a class is added to each nav menu item when the scroll bar passes their respective part of the HTML. I believe I already know how to add classes to my navmenu items, so is there a specific way in JS to identify where in the DOM the user is?

To change the classes in the navbar dynamically, I use something like:

jQuery(document).ready(function ($) {

        var menu_items_links = $(".menu li a");
        menu_items_links.each(function () {
            if ($(this).is('[href*="#CURRENT LOCATION IN DOM"]')) {
                $(this).parent().addClass('current-location');
            }
        })
    });

Where the class will add the highlight/underline to the navmenu item to show that the user is at the specific location.


Solution

  • So what finally worked for me was using WaypointJS. I basically just set waypoints at the specific parts of the DOM and then I could define what I want to happen at those places. Here's the code in the end:

    jQuery(document).ready(function ($) {
    
        var menu_items_links = $(".menu li a");
        menu_items_links.each(function () {
            if ($(this).is('[href*="#"]')) {
                $(this).parent().removeClass('current-menu-item current-menu-ancestor');
            }
        })
        
        new Waypoint({
          element: document.getElementById('explore'),
          direction: 'down',
          handler: function() {
            console.log("FIRST WAYPOINT IS ACTIVE.");
            document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.add('current-menu-item', 'current-menu-ancestor');
            document.querySelector("a[href='/manitoba/#build']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
            document.querySelector("a[href='/manitoba/#connect']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
          },
          offset: '25%',
          continuous: false
      });  
    
      new Waypoint({
        element: document.getElementById('explore'),
        direction: 'up',
        handler: function() {
          console.log("DEACTIVATING WAYPOINT.");
          document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
        },
        offset: '35%',
    });  
    
      new Waypoint({
        element: document.getElementById('build'),
        handler: function() {
          console.log("SECOND WAYPOINT IS ACTIVE.");
          document.querySelector("a[href='/manitoba/#build']").parentElement.classList.add('current-menu-item', 'current-menu-ancestor');
          document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
          document.querySelector("a[href='/manitoba/#connect']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
        },
        offset: '50%',
        continuous: false
    }); 
    
    new Waypoint({
        element: document.getElementById('connect'),
        handler: function() {
          console.log("THIRD WAYPOINT IS ACTIVE.");
          document.querySelector("a[href='/manitoba/#connect']").parentElement.classList.add('current-menu-item', 'current-menu-ancestor');
          document.querySelector("a[href='/manitoba/#build']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
          document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
        },
        offset: '50%',
        continuous: false
        });  
    });