document.addEventListener('DOMContentLoaded', function() { var navItems = Array.prototype.slice.call( document.querySelectorAll('.timeline-nav-item') ); var steps = Array.prototype.slice.call( document.querySelectorAll('.timeline-step') ); var progress = document.querySelector('.timeline-progress'); var line = document.querySelector('.timeline-line'); if ( !navItems.length ) return; function activateStep( step ){ step = parseInt( step, 10 ); navItems.forEach(function( el ){ el.classList.remove('active'); }); steps.forEach(function( el ){ el.classList.remove('active'); }); var navItem = navItems.filter(function( el ){ return parseInt(el.dataset.step, 10) === step; })[0]; steps.filter(function( el ){ return parseInt(el.dataset.step, 10) === step; }) .forEach(function( el ){ el.classList.add('active'); }); if ( navItem ) navItem.classList.add('active'); // Compute the height of the red progress bar so it reaches down to // the middle of the active nav item. if ( navItem && line && progress ){ var lineTop = line.getBoundingClientRect().top + window.pageYOffset; var rect = navItem.getBoundingClientRect(); var itemMid = rect.top + window.pageYOffset + navItem.offsetHeight / 2; var height = Math.max( 0, itemMid - lineTop ); progress.style.height = height + 'px'; } } navItems.forEach(function( el ){ el.addEventListener('click', function(){ activateStep( this.dataset.step ); }); }); // Keyboard navigation with arrow keys document.addEventListener('keydown', function( e ){ var active = navItems.filter(function( el ){ return el.classList.contains('active'); })[0]; if ( !active ) return; var step = parseInt( active.dataset.step, 10 ); if ( e.key === 'ArrowDown' || e.key === 'ArrowRight' ){ if ( step < navItems.length ){ activateStep(step + 1); e.preventDefault(); } } if ( e.key === 'ArrowUp' || e.key === 'ArrowLeft' ){ if ( step > 1 ){ activateStep(step - 1); e.preventDefault(); } } }); // Init: run once, then re-run after fonts/layout settle so the bar is sized correctly activateStep(1); function reflowActive(){ var active = navItems.filter(function( el ){ return el.classList.contains('active'); })[0]; if ( active ) activateStep( active.dataset.step ); } window.addEventListener('load', reflowActive); window.addEventListener('resize', reflowActive); });