Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nav menu indicator - sliding on hover, on click, and on scroll

Tags:

javascript

I've never asked a question here, but I've made use of many answers so am hoping that the effect I'm hoping to achieve will also help others looking to achieve the same effect.

I'm currently working on a client's website and have uploaded it to my dropbox for this question: http://dl.dropboxusercontent.com/u/62164771/stage/cw/index16042013.html

It currently uses a few different scripts to achieve the following:

(this script is in the head area) The navigation menu is fixed, and when you click on a menu link, the page scrolls to the relevant section. When the page scrolls to the relevant section (after being clicked on), a class (.act) is added to the active menu link. The .act class is also added when the user scrolls up and down in the page with their mouse/track pad or whatever.

(this script is at the bottom of the page) Another effect is also added to the nav bar links: When you hover over a nav item, a nav menu indicator arrow (a div with a background image of an arrow) slides across to the hovered link.

So this is what I want to happen

Currently the nav menu indicator arrow only slides on hover. I want it to slide to the active link when it is clicked and stay there until the user hovers on another link. My current script is a little buggy with the menu indicator not always sliding to the active link.

I also want the nav menu indicator arrow to slide to the active link when the user scrolls through the page.

Is this achievable?

Relevant Scripts

Script 1 - scroll smoothly to section and activate 'act' class when scrolling:

<script type="text/javascript">
  jQuery(document).ready(function( $ ) {
    $('nav a').on('click', function() {
      var scrollAnchor = $(this).attr('data-scroll'),
      scrollPoint = $('section[data-anchor="' + scrollAnchor + '"]')
        .offset().top + 1;
      $('body,html').animate({
        scrollTop: scrollPoint
      }, 500);
      return false;
    })

    $(window).scroll(function() {
      var windscroll = $(window).scrollTop();
      if (windscroll >= 100) {
        $('#wrap section').each(function(i) {
          if ($(this).position().top <= windscroll + 200) {
            $('nav a.act').removeClass('act');
            $('nav a').eq(i).addClass('act');
          }
        });
      } else {
        $('nav').removeClass('fixed');
        $('nav a.act').removeClass('act');
        $('nav a:first').addClass('act');
      }

    }).scroll();
  })
</script>

Script 2 - For sliding the main-menu-indicator to the position of the hovered and active links

<script type="text/javascript">
$('#header')
  .css('position', 'relative')
  .append(
    $('<div>').attr('id', 'main-menu-indicator')
  )
  menuHover = function(which){

    if(which==null)
      which = $('ul#main-menu a.act')
    $('#main-menu-indicator')
      .stop(true, false)
      .animate({
        left: ($(which).offset().left - $('#header').offset().left +
          $(which).width()/2 + parseInt($(which).css('paddingLeft')) -
          $('#main-menu-indicator').width()/2 )
      }, 500)
  } 

$('ul#main-menu a')
  .hover(
    function(){
      menuHover(this)
    },
    function(){
      menuHover(null)
    }
  ) 
</script>
like image 375
benjaminties Avatar asked Nov 30 '25 16:11

benjaminties


1 Answers

You can use Bootstrap ScrollSpy to get the desired effect, it might be easier to implement than writing your own solution. You could start the animation using the activate event.

In your case you could set <a href="#top">, you currently have a section and an article with the same id, you should get rid of one of those as it is invalid html to have more than one element with the same id, and it might break things. For example keep the id on the article: <article class="top area" id="top">. Include the ScrollSpy script on the page and add:

$('.header').scrollspy({activate: function() {
  // Add your logic here.
  }
});

Inside the activate function $('nav li.active') will give you the currently active li, with that info you should be able to work out where to move your arrow, and you can then run your smooth scrolling arrow code to move the arrow to the right place.

Now ScrollSpy takes care of calling activate when the user scrolls somewhere, and you react on that by moving the arrow to the right place.

like image 153
tom-19 Avatar answered Dec 02 '25 05:12

tom-19



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!