Essentially, the issue can be broken down into two main components:
1. Identifying the Location of Each Section on the Page
In order to emphasize a navigation element for each section, it's crucial to first determine the exact location of each section.
I recommend using a class such as .section
to define your sections and assigning a name
attribute to differentiate between them. Your markup should resemble something like this:
<html>
<head>...etc.</head>
<body>
<ul>
<li class="nav" id="nav_one">1</li>
<li class="nav" id="nav_two">2</li>
</ul>
<div class="section" name="one"> Section one</div>
<div class="section" name="two"> Section two</div>
</body>
</html>
Use JavaScript to locate the position of each section:
//define a sections object
var sections = {}
//find all sections on the page, then for each:
$('.section').each(function(){
//add a property to the object with a key corresponding to the name
//and a value corresponding to the offset from the top of the page.
sections[$(this).attr('name')] = $(this).offset().top;
});
2. Determining the User's Position on the Page
The second aspect involves identifying which sections are currently in view. This dynamic changes as the user scrolls, necessitating the use of jQuery's scroll()
event handler:
//the function passed as an argument will be called every time the user scrolls.
$(document).scroll(function(){
//get the new position
var newPos = $(this).scrollTop();
//configurable variable to decide how close a new section needs to be to the
//top of the page before it's considered the active one.
var OFFSET = 100;
//analyze all sections and determine the active one based on proximity to the top
for(name in sections){
if(sections[name] > newPos && sections[name] < newPos + OFFSET){
//the section with name = name is within OFFSET of the top
//remove "active" styling from the previously active nav elements
$('.nav').removeClass('active');
//set the nav element with an id of nav_sectionname as active
$('#nav_' + name).addClass('active');
}
}
});
Check out this Codepen example for reference