Vertical sticky navigation Menu selects wrong link when going down

798 views Asked by At

I am following this tutorial to build a custom sticky navigation menu with scrolling.

I am using the following jQuery plugins:

When clicking on the links, the scrolling is working as desired; however; the .selected class is not being applied correctly to the menu link when it is clicked and the direction is downwards.

For example:

  • Menu item 1
  • Menu item 2
  • Menu item 3

When page loads, Menu item 1 is highlighted with the .selected class.

When we click on the Menu item 2 the scrolling happens but the highlighting does not.

Now, if we click on Menu item 3 the scrolling happens and the Menu item 2 is highlighted instead of the Menu item 3

This is the code I am using:

<nav class="section-navigation">
    <ul>
        <li><h5><a href="#item-1">item A</a></h5></li>
        <li><h5><a href="#item-2">item B</a></h5></li>
        <li><h5><a href="#item-3">item C</a></h5></li>        
        <li><h5><a href="#item-4">item D</a></h5></li>
    </ul>
</nav>

<div class="section-content" id="item-1">some content for this section</div>
<div class="section-content" id="item-2">some content for this section</div>
<div class="section-content" id="item-3">some content for this section</div>
<div class="section-content" id="item-4">some content for this section</div>

jQuery('.section-navigation').waypoint('sticky', {
  offset: 90 // Apply "stuck" when element 30px from top
});

jQuery(function() {
  var sections = jQuery('.section-content');
  var navigation_links = jQuery('nav a');

  sections.waypoint({
    handler: function(event, direction) {
      var active_section;
      active_section = jQuery(this);

      if (direction === "up") active_section = active_section.prev();

      var active_link = jQuery('nav a[href="#' + active_section.attr("id") + '"]');
      navigation_links.closest('li').removeClass("selected");
      active_link.closest('li').addClass("selected");

    },
    offset: '-20px'
  });

   jQuery('nav a[href^="#"]').on('click', function(event) {
    event.preventDefault();
    jQuery.scrollTo(
      jQuery(this).attr("href"),
      {
        duration: 200,
        //offset: { 'left':0, 'top':-0.15*jQuery(window).height() }
        offset: { 'top':+0.15 }
      }
    );

  }); 
});

I found three more related questions but none of them give an answer to solve my problem:

Please help me on solving this. Thank you.

EDIT: Here is the fiddle: http://jsfiddle.net/uteqm28v/2/

2

There are 2 answers

0
Gixty On BEST ANSWER

After banging my head to the wall, I finally fixed the code I had. It was very simple fix.

I just had to remove event from the handler and set both offset to the same number of pixels (they can be opposite, one positive and one negative).

Here is the working fiddle http://jsfiddle.net/uteqm28v/5/

And the code:

$('.section-navigation').waypoint('sticky', {
  offset: 30 // Apply "stuck" when element 30px from top
});

jQuery(function() {
    var sections = jQuery('.section-content');
    var navigation_links = jQuery('nav a');

  sections.waypoint({
    handler: function(direction) {
      var active_section;
      active_section = jQuery(this);

      if (direction === "up") active_section = active_section.prev();
      var active_link = jQuery('nav a[href="#' + active_section.attr("id") + '"]');
      navigation_links.closest('li').removeClass("selected");
      active_link.closest('li').addClass("selected");

    },
    offset: '20px' //this can be negative
  });

   jQuery('nav a[href^="#"]').on('click', function(event) {
    event.preventDefault();
    jQuery.scrollTo(
      jQuery(this).attr("href"),
      {
        duration: 200,
        //offset: { 'left':0, 'top':-0.15*jQuery(window).height() }
        offset: { 'top':20 }
      }
    );

  }); 
});
1
prog1011 On

Try this code

`

$('.section-navigation').waypoint('sticky', {
  offset: 30 // Apply "stuck" when element 30px from top
});
 var previousScroll = 0;
 var  drctn = '';
var linkClk = false;
(function () {    
    $(window).scroll(function () {
       var currentScroll = $(this).scrollTop();
       if (currentScroll > previousScroll){
           drctn='down';           
       }
       else {
          drctn='up';          
       }
       previousScroll = currentScroll;
    });
}());

jQuery(function() {
    var sections = jQuery('.section-content');
    var navigation_links = jQuery('nav a');

  sections.waypoint({
    handler: function(event, direction) {
      var active_section;
      active_section = jQuery(this);    
        if(linkClk){
            linkClk=false;
            if (drctn=='down'){            
               active_section = active_section.next();    
           }
           var  active_link = jQuery('nav a[href="#' + active_section.attr("id") + '"]');


      navigation_links.closest('li').removeClass("selected");
      active_link.closest('li').addClass("selected");
        }
        else
            {
                if (direction === "up") active_section = active_section.prev();

      var active_link = jQuery('nav a[href="#' + active_section.attr("id") + '"]');
      navigation_links.closest('li').removeClass("selected");
      active_link.closest('li').addClass("selected");
            }



    },
    offset: '-20px'
  });

   jQuery('nav a[href^="#"]').on('click', function(event) {       
       linkClk = true;
    event.preventDefault();
       //jQuery('nav a').closest('li').removeClass("selected");
       //jQuery(this).closest('li').addClass("selected");
    jQuery.scrollTo(        
      jQuery(this).attr("href"),
      {
        duration: 200,
        //offset: { 'left':0, 'top':-0.15*jQuery(window).height() }
        offset: { 'top':+0.15 }

      }
    );

  }); 
});

`

Demo JsFiddle here