tags:

views:

119

answers:

3

I have a single page website which has a fixed floating nav. I want to be able to highlight which section the user is on by adding a class of say "on" to the relevant navigation a tag.

This class will need to be removed when the user is no longer on that section and the new current section then needs to be reflected in the nav.

This can't be done via a click function, as the user could still just scroll up and down the page. I have know idea if this can even be done or where to start as my jQuery is VERY limited.

Any help would be really appreciated.

Here is my current webpage, which doesn't have any active nav highlighting: http://ec2.dragonstaff.com/www.creativegems.co.uk/

A: 

You could grab the window's scrollTop with

var scrollTop=$(window).scrollTop();

http://api.jquery.com/scrollTop

Then you go through the content <div>s and cumulatively add their height up until you get to a value that is close enough to scrollTop. You probably have to experiment a little with regards to how you handle overlap.

Once you figured that your are scrolled to the content of, say, your portfolio you add the relevant class to the nav element.

Lenni
A: 

Check out this similar question for an idea on how to accomplish this: http://stackoverflow.com/questions/2337630/find-html-element-nearest-to-position-relative-or-absolute

methodin
+1  A: 

This seems to work with your site:

var $sections = $('section');  // all content sections
var $navs = $('nav > ul > li');  // all nav sections

var topsArray = $sections.map(function() {
    return $(this).position().top - 300;  // make array of the tops of content
}).get();                                 //   sections, with some padding to
                                          //   change the class a little sooner
var len = topsArray.length;  // quantity of total sections
var currentIndex = 0;        // current section selected

var getCurrent = function( top ) {   // take the current top position, and see which
    for( var i = 0; i < len; i++ ) {   // index should be displayed
        if( top > topsArray[i] && topsArray[i+1] && top < topsArray[i+1] ) {
            return i;
        }
    }
};

   // on scroll,  call the getCurrent() function above, and see if we are in the
   //    current displayed section. If not, add the "selected" class to the
   //    current nav, and remove it from the previous "selected" nav
$(document).scroll(function(e) {
    var scrollTop = $(this).scrollTop();
    var checkIndex = getCurrent( scrollTop );
    if( checkIndex !== currentIndex ) {
        currentIndex = checkIndex;
        $navs.eq( currentIndex ).addClass("selected").siblings(".selected").removeClass("selected");
    }
});
patrick dw
This worked perfectly, thanks Patrick.The only change I had to make was in siblings as it need to know it was a class:siblings(".selected")
richardpixel
@Richardpixel - Ah yes, I had missed the `.`. Fixed. Glad you caught it and that it worked for you. :o)
patrick dw
After some more testing this doesn't actually seem to work in IE (6,7,8 or 9). Don't suppose you have any ideas why that might be happening?
richardpixel
@richardpixel - Depends on what isn't working. Does the `.scroll()` handler fire at all? If you're not sure. Place an alert in the top of the handler. If you find that it's not firing, then try `$('body').scroll(func...` instead of `$(document).scroll(func...`.
patrick dw
Thanks for your help and you were in the right place, but I needed $(window).scroll(func....
richardpixel