Progress Nav is a nice side table of contents menu and navigation system that allows the current navigation element to be marked with an animated progress line when scrolling through a web page.
responsive table of contents, html table of content, tocify title table of contents, animated side navigation bar
Pure CSS Progress Bar Scroll Depth Indicator Library
How to make use of it:
1. Create a table of contents and navigation with corresponding content sections and an SVG-based progress bar.
<nav class="toc"> <ul> <li><a href="#section1">Section One</a></li> <li> <a href="#section2">Section Two</a> <ul> <li><a href="#section21">Section 2-1</a></li> <li><a href="#section22">Section 2-2</a></li> <li><a href="#section23">Section 2-3</a></li> </ul> </li> </ul> <svg class="toc-marker" width="200" height="200" xmlns="http://www.w3.org/2000/svg"> <path stroke="#444" stroke-width="3" fill="transparent" stroke-dasharray="0, 0, 0, 1000" stroke-linecap="round" stroke-linejoin="round" transform="translate(-0.5, -0.5)" /> </svg> </nav>
<article class="contents"> <section id="section1"> <h2>Section One</h2> </section> <section> <div id="section2"> <h2>Section Two</h2> </div> <div id="section21"> <h3>Section 2-1</h3> </div> <div id="section22"> <h3>Section 2-2</h3> </div> </section> ...... </article>
2. Design the table of contents and navigation.
.toc { position: fixed; left: 3em; top: 5em; padding: 1em; width: 14em; line-height: 2; } .toc ul { list-style: none; padding: 0; margin: 0; } .toc ul ul { padding-left: 2em; } .toc li a { display: inline-block; color: #aaa; text-decoration: none; -webkit-transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); } .toc li.visible > a { color: #111; -webkit-transform: translate(5px); transform: translate(5px); } .toc-marker { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; } .toc-marker path { -webkit-transition: all 0.3s ease; transition: all 0.3s ease; }
3. Main javascript:
var toc = document.querySelector( '.toc' ); var tocPath = document.querySelector( '.toc-marker path' ); var tocItems; // Factor of screen size that the element must cross // before it's considered visible var TOP_MARGIN = 0.1, BOTTOM_MARGIN = 0.2; var pathLength; window.addEventListener( 'resize', drawPath, false ); window.addEventListener( 'scroll', sync, false ); drawPath(); function drawPath() { tocItems = [].slice.call( toc.querySelectorAll( 'li' ) ); // Cache element references and measurements tocItems = tocItems.map( function( item ) { var anchor = item.querySelector( 'a' ); var target = document.getElementById( anchor.getAttribute( 'href' ).slice( 1 ) ); return { listItem: item, anchor: anchor, target: target }; } ); // Remove missing targets tocItems = tocItems.filter( function( item ) { return !!item.target; } ); var path = []; var pathIndent; tocItems.forEach( function( item, i ) { var x = item.anchor.offsetLeft - 5, y = item.anchor.offsetTop, height = item.anchor.offsetHeight; if( i === 0 ) { path.push( 'M', x, y, 'L', x, y + height ); item.pathStart = tocPath.getTotalLength() || 0; } else { // Draw an additional line when there's a change in // indent levels if( pathIndent !== x ) path.push( 'L', pathIndent, y ); path.push( 'L', x, y ); // Set the current path so that we can measure it tocPath.setAttribute( 'd', path.join( ' ' ) ); item.pathStart = tocPath.getTotalLength() || 0; path.push( 'L', x, y + height ); } pathIndent = x; tocPath.setAttribute( 'd', path.join( ' ' ) ); item.pathEnd = tocPath.getTotalLength(); } ); pathLength = tocPath.getTotalLength(); sync(); } function sync() { var windowHeight = window.innerHeight; var pathStart = Number.MAX_VALUE, pathEnd = 0; var visibleItems = 0; tocItems.forEach( function( item ) { var targetBounds = item.target.getBoundingClientRect(); if( targetBounds.bottom > windowHeight * TOP_MARGIN && targetBounds.top < windowHeight * ( 1 - BOTTOM_MARGIN ) ) { pathStart = Math.min( item.pathStart, pathStart ); pathEnd = Math.max( item.pathEnd, pathEnd ); visibleItems += 1; item.listItem.classList.add( 'visible' ); } else { item.listItem.classList.remove( 'visible' ); } } ); // Specify the visible path or hide the path altogether // if there are no visible items if( visibleItems > 0 && pathStart < pathEnd ) { tocPath.setAttribute( 'stroke-dashoffset', '1' ); tocPath.setAttribute( 'stroke-dasharray', '1, '+ pathStart +', '+ ( pathEnd - pathStart ) +', ' + pathLength ); tocPath.setAttribute( 'opacity', 1 ); } else { tocPath.setAttribute( 'opacity', 0 ); } }
Animated Side TOC Nav For Long Web Content Plugin/Github
See Demo And Download
Official Website(hakimel): Click Here
This superior jQuery/javascript plugin is developed by hakimel. For extra Advanced Usages, please go to the official website.