Jens Kvist Jens Kvist - 3 months ago 13
Javascript Question

Highlight Menu Item when Scrolling Down to Section

I know this question have been asked a million times on this forum, but none of the articles helped me reach a solution.

I made a little piece of jquery code that highlights the hash-link when you scroll down to the section with the same id as in the hash-link.

$(window).scroll(function() {
var position = $(this).scrollTop();

$('.section').each(function() {
var target = $(this).offset().top;
var id = $(this).attr('id');

if (position >= target) {
$('#navigation > ul > li > a').attr('href', id).addClass('active');
}
});
});


The problem now is that it highlights all of the hash-links instead of just the one that the section has a relation to. Can anyone point out the mistake, or is it something that I forgot?

Answer

Instead of adding the .active class to all the links, you should identify the one which attribute href is the same as the section's id.

Then you can add the .active class to that link and remove it from the rest.

Here you have a snippet:

$(window).scroll(function() {

    var position = $(this).scrollTop();

    $('.section').each(function() {
        var target = $(this).offset().top;
        var id = $(this).attr('id');
        
        if (position >= target) {
            $('#navigation > ul > li > a').removeClass('active');
            $('#navigation > ul > li > a[href=#' + id + ']').addClass('active');
        }
    });
});
#sections {
    position: absolute;
    top: 0;
    left: 120px;
}
#navigation {
    position: fixed;
    top: 0;
    left: 0;
}
.section {
    height: 200px;
}
#section5 { 
    height:1000px;
}
.active {
    background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navigation">
    <ul>
        <li><a href="#section1">Section 1</a></li>
        <li><a href="#section2">Section 2</a></li>
        <li><a href="#section3">Section 3</a></li>
        <li><a href="#section4">Section 4</a></li>
        <li><a href="#section5">Section 5</a></li>
    </ul>
</div>
<div id="sections">
    <div id ="section1" class="section">
        I'm section 1
    </div>
    <div id ="section2" class="section">
        I'm section 2
    </div>
    <div id ="section3" class="section">
        I'm section 3
    </div>
    <div id ="section4" class="section">
        I'm section 4
    </div>
    <div id ="section5" class="section">
        I'm section 5
    </div>
</div>

Hope it helps!

EDIT:

In the current snippet, the links will get highlighted when the section reaches the very top of the page. If you want them highlighted when they are getting close, you can add a small margin in this way:

if (position + my_margin >= target) {