Fixed navigation (scrolling to content headings)

I used http://www.distractedbysquirrels.com/blog/one-page-layout-with-fixed-navigation-and-jquery/ as a foundation for a fixed navigation/scrolling type page, and modified it so it was a bit nicer and more adaptable, like this:

$(document).ready(function() {
	// Parameters
	var navOffset 	= 15,
		scrollSpeed = 500;
		animationSpeed = 100;
		cssClass = 'scrollNavOn';
		minTop = $('#content').offset().top,
		maxTop = $('#content').height() + minTop - $('#navigation').height();	
		
	// Place navigation
	var currentScroll = $(window).scrollTop();
	$('#navigation').css({'top' : minTop});
	
	// Align navigation after loading while scrolling through the content
	if( currentScroll > minTop && currentScroll < maxTop ) 
		$('#navigation').css({'top' : navOffset + 'px'});	
	
	// Adjust navigation top to content top and end of content
	if( currentScroll <= minTop ) 
		$('#navigation').css({'top' : minTop - currentScroll});
	if( currentScroll >= maxTop ) 
		$('#navigation').css({'top' : maxTop - currentScroll});
	
	// Get section positions to use later
	var sections = [];
	$('.scroller-sections').each(function() {
		sections.push([$(this).attr('id'), Math.floor($(this).offset().top)]);
		var currentSection = $(this);		
	});
	
	// Set the click functionality for the nav
	$("#scroller-navigation li:not(.notsection)").each(function(index) {
		$(this).click(function (event) {
			event.preventDefault();
			var targetOffset = sections[index][1] - navOffset;
			$('html,body').animate({scrollTop:targetOffset}, scrollSpeed);
		});
	});

	// On scroll highlight the correct nav item
	newNavIndex = 0;
	$(window).scroll(function() {
		// Current scroll
		var winScroll = $(window).scrollTop();
		
		// Align navigation to window scroll while scrolling through content
		if( winScroll > minTop && winScroll < maxTop )
			$('#scroller-navigation').css({'top' : navOffset + 'px'});
			
		// Adjust navigation top to content top and end
		if( winScroll <= minTop ) 
			$('#scroller-navigation').css({'top' : minTop - winScroll});
		if( winScroll >= maxTop ) 
			$('#scroller-navigation').css({'top' : maxTop - winScroll});
		
		// Iterate through the different sections and work out which nav element to highlight
		for(var i = 0; i < sections.length; i++) {
			// Work out which section we are on - get the top of our current section and the top of the next section
			var lowerLimit = sections[i][1] - navOffset
			var upperLimit = $(document).height(); // If we are on the last section  set upperlimit to be document height
			if(i < sections.length - 1) 
				upperLimit = sections[i + 1][1];

			// Run through each section height and see whether it's between the upper and lower limits, and also whether we've scrolled down to the end of the document
			if(	((winScroll + navOffset) < upperLimit && (winScroll + navOffset) > lowerLimit) || 
				(i == sections.length - 1 && (winScroll + $(window).height() == $(document).height()))	) {
				// $('#scroller-navigation li:nth-child(' + (i + 1) + ')').css({'font-weight' : 'bold'});

				$('#scroller-navigation li:nth-child(' + (i + 1) + ')').addClass(cssClass, animationSpeed);
				$("#scroller-navigation li:not(.notsection)").each(function(index) {
					if(i != index)
						$(this).removeClass(cssClass, animationSpeed/2);
				});				
			}
		}
	});		
});

With HTML like this:

<html> 
  <head> Add your CSS and JS here </head> 
  <body> 
    <div id="wrapper"> 
      <div id="sidebar"> 
        <ul id="scroller-navigation"> 
          <li>List your nav items here</li> 
        </ul> 
      </div> 
      <div id="content"> 
        <div class="scroller-sections" id="uniqueid"> 
          <h2>Heading</h2> 
          <p>Content</p> 
        </div> 
      </div> 
    </div> 
  </body> 
</html>

What someone really needs to do now is automatically build the <li>s based on how many h2s (or whatever, that should be passed in as a parameter I guess) there are in the text and set the nav up automatically.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>