on page navigation IntersectionObserver
by hohoya33
HTML
<div class="slide slide--intro">
<h1>On page navigation Demo</h1>
</div>
<nav>
<ul>
<li><a class="active" href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
<li><a href="#four">Four</a></li>
<li><a href="#five">Five</a></li>
</ul>
</nav>
<section id="one">
<p>Slide One</p>
</section>
<section id="two">
<p>Slide Two</p>
</section>
<section id="three">
<p>Slide Three</p>
</section>
<section id="four">
<p>Slide Four</p>
</section>
<section id="five">
<p>Slide Five</p>
</section>
CSS
.slide {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.slide--intro {
flex-direction: column;
}
nav {
position: sticky;
width: 100%;
top: 0;
left: 0;
right: 0;
background-color: #fff;
}
nav ul {
list-style-type: none;
display: flex;
align-items: center;
justify-content: space-around;
width: 100%;
max-width: 800px;
height: 50px;
margin: 0 auto;
padding: 0;
}
nav li {
display: inline-block;
padding: 5px;
}
nav a {
display: block;
height: 40px;
padding: 0 20px;
line-height: 40px;
text-decoration: none;
text-transform: uppercase;
color: #323232;
font-weight: bold;
border-radius: 4px;
transition: background-color 0.3s ease-in;
}
nav a:hover,
nav a:active,
nav a:focus {
background-color: rgba(184,214,168,0.5);
}
nav a.active {
background-color: rgba(184,214,168,0.5);
}
section {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
p {
text-align: center;
color: #fff;
font-size: 3.5em;
font-weight: bold;
text-transform: uppercase;
}
#one {
background-color: #6ca392;
}
#two {
background-color: #ffa58c;
}
#three {
background-color: #ff4f30;
}
#four {
background-color: #576b51;
}
#five {
background-color: #392a1b;
}
JavaScript
const changeNav = (entries, observer) => {
entries.forEach((entry) => {
// verify the element is intersecting
if(entry.isIntersecting && entry.intersectionRatio >= 0.55) {
// remove old active class
document.querySelector('.active').classList.remove('active');
// get id of the intersecting section
var id = entry.target.getAttribute('id');
// find matching link & add appropriate class
var newLink = document.querySelector(`[href="#${id}"]`).classList.add('active');
}
});
}
// init the observer
const options = {
threshold: 0.55
}
const observer = new IntersectionObserver(changeNav, options);
// target the elements to be observed
const sections = document.querySelectorAll('section');
sections.forEach((section) => {
observer.observe(section);
});