Changing the active menu item when scrolling

Changing the active menu item when scrolling

So let’s figure it out. Let’s write the simplest html.

Html

<nav class="nav">
<ul>
<li><a href="#" class="active">One</a></li>
<li><a href="#">Two</a></li>
<li><a href="#">Three</a></li>
<li><a href="#">Four</a></li>
<li><a href="#">Five</a></li>
</ul>
</nav>

<section class="section"></section>
<section class="section"></section>
<section class="section"></section>
<section class="section"></section>
<section class="section"></section>
<script src="script.js"></script>

It’s just that sections and their associated navigation elements are links.

CSS

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.nav {
position: fixed;
left: 0;
top: 0;
width: 100%;
background-color: #131313;
padding: 20px;
}

ul {
display: flex;
list-style-type: none;
}

a {
text-decoration: none;
color: #fff;
font-family: sans-serif;
display: inline-block;
margin-right: 25px;
}

a.active {
color: red;
}

.section {
height: 100vh;
border: 1px solid #000;
}

A bit of CSS to keep things cool and also to create a class active and set the dimensions to the sections.

Js

window.addEventListener('scroll', () => {
let scrollDistance = window.scrollY;

if (window.innerWidth > 768) {
document.querySelectorAll('.section').forEach((el, i) => {
if (el.offsetTop - document.querySelector('.nav').clientHeight <= scrollDistance) {
document.querySelectorAll('.nav a').forEach((el) => {
if (el.classList.contains('active')) {
el.classList.remove('active');
}
});

document.querySelectorAll('.nav li')[i].querySelector('a').classList.add('active');
}
});
}
});

Well, and a relatively simple JS:

  1. We go through all sections on the site
  2. We look, if the indent at the top of the section is less or equal to the scroll indicator – then we go through the links and the desired link (through the index) set the class

In general, that’s all, very simple code. Hope it helps you. The sources are below, and the video is at the beginning of the post)

Good luck!

Leave a Reply

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