Question

I'm using jQuery to guide my pages scrolling and change the color of a nav item to correspond to the section you're in. Everything's working well, but the script is ignoring the last section on the page (Contact).

This is largely based on another question here on Stack, but I've modified the code to fit my needs and then ran into the issue.

Test site: http://dev4.dhut.ch/

HTML:

<nav>
    <ul>
        <li class="active"><a href="#music" title="Music">MUSIC</a></li>
        <li><a href="#photos" title="Photos">PHOTOS</a></li>
        <li><a href="#lyrics" title="Lyrics">LYRICS</a></li>
        <li><a href="#news" title="News">NEWS</a></li>
        <li><a href="#info" title="Info">INFO</a></li>
        <li><a href='#contact' title="Contact">CONTACT</a></li>
    </ul>
    <span></span>
</nav>

JavaScript:

var $sections    = $('section'),
    $navs        = $('nav > ul > li'),
    topsArray    = $sections.map(function(){
                       return $(this).position().top - 100;
                   }).get(),
    len          = topsArray.length,
    currentIndex = 0,
    getCurrent   = function(top){
                       for(var i = 0; i < len; i++){
                           if(top > topsArray[i] && topsArray[i+1] && top < topsArray[i+1]){
                               return i;
                           }
                       }
                   };

$(document).scroll(function(e){
    var scrollTop  = $(this).scrollTop(),
        checkIndex = getCurrent( scrollTop );

    if( checkIndex !== currentIndex ){
        currentIndex = checkIndex;
        $navs.eq( currentIndex ).addClass('active').siblings('.active').removeClass('active');
    }
});
Was it helpful?

Solution

I think the following line is where the problem lies:

if(top > topsArray[i] && topsArray[i+1] && top < topsArray[i+1]){

Specifically topsArray[i+1] is undefined for the last iteration of i. Try pushing one more value into topsArray that includes the height of the entire page.

topsArray = $sections.map(function(){
               return $(this).position().top - 100;
            }).get(),
topsArray.push(document.height);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top