Scrolly Nav
Update nav on scroll
by kthornbloom
HTML
<div class="body">
<nav>
<ul id="nav"></ul>
</nav>
<div class="page">
<section class="content-section" id="Introduction"><h3>Intro</h3> Set each section with an id for the nav element associated and a class of content-section</section>
<section class="content-section" id="Materials-and-things">Materials Needed</section>
<section class="content-section" id="Setup">How to do the setup</section>
<section class="content-section" id="Step-one">Step One: do the thing</section>
<section class="content-section" id="Conclusion">The end.</section>
</div>
</div>
SCSS
.body {
font-family:sans-serif;
line-height: 1.3em;
display: flex;
height: 100%;
max-width: 100%;
width: 100vw;
}
nav {
background: #eee;
width: 200px;
a:link, a:visited {
display: block;
padding: 10px;
width: 100%;
}
}
.page {
flex-grow: 1;
overflow: auto;
height: 100vh;
}
section {
border-bottom: 2px solid #ddd;
padding: 10px;
height: 100vh;
z-index:2;
padding: 30px;
position: relative;
}
.current {
background:#bbb;
}
a:link, a:visited {
color:inherit;
text-decoration: none;
}
* {
box-sizing:border-box;
}
h3 {
font-size: 1.2em;
}
JavaScript
let observerOptions = {
root: null,
rootMargin: "50px",
threshold: .2
};
const imageObserver = new IntersectionObserver((entries, imgObserver) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const currentSection = entry.target
let sectionIndex = indexInParent(entry.target);
let currentNav = document.querySelectorAll('#nav li a')[sectionIndex];
let prevNav = document.querySelectorAll('.current');
prevNav.forEach((i) => {
i.classList.remove('current');
})
currentNav.classList.add('current')
}
})
}, observerOptions);
// Populate Nav
const arr = document.querySelectorAll('.content-section')
arr.forEach((v) => {
let navItem = v.getAttribute('id');
navItem = navItem.replace(/-/g, ' ');
var node = document.createElement("LI");
node.innerHTML = '<a href="#'+navItem+'">'+navItem+'</a>';
document.getElementById("nav").appendChild(node);
imageObserver.observe(v);
})
function indexInParent(node) {
var children = node.parentNode.childNodes;
var num = 0;
for (var i=0; i<children.length; i++) {
if (children[i]==node) return num;
if (children[i].nodeType==1) num++;
}
return -1;
}