I’m trying to detect whenever a visitor has scrolled past elements on a page.
I would like to detect scrolling past every .title
element, and add an .active
class to the corresponding anchor menu item. The .active
class should stay on the anchor menu item until scrolling past the next title element.
Here is what I have – adding the .active
class works, but removing it fails.
Anyone able to help?
window.addEventListener("scroll", function () {
document.querySelectorAll('.title').forEach((section) => {
const id = section.getAttribute('id');
if (id) {
if (window.scrollY > (section.offsetTop + section.offsetHeight)) {
document.querySelector(`.menu li a[href="#${id}"]`).classList.add('active');
} else {
document.querySelector(`.menu li a.active`).classList.remove('active');
}
}
});
});
.active {
color: red
}
<ul class="menu">
<li><a href="#one">Link one</a></li>
<li><a href="#two">Link two</a></li>
<li><a href="#three">Link thre</a></li>
<li><a href="#four">Link four</a></li>
<li><a href="#five">Link five</a></li>
</ul>
<div class="container">
<div class="title" id="one">Title one</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec cursus dolor id ullamcorper tempor. Donec ut ullamcorper tellus. Etiam vel rhoncus urna. Aenean augue nulla, congue a orci at, imperdiet vehicula eros. Aenean ornare nibh ut leo faucibus fringilla. Quisque varius ut ipsum egestas feugiat. Mauris id nisl ultrices, consectetur mauris in, consectetur mi. Sed sit amet dolor urna. Nullam nec enim gravida, pulvinar lacus ut, volutpat nibh. Quisque commodo eu tortor ac dictum. Vivamus sodales risus sed blandit vulputate. Proin elit erat, varius non tincidunt ut, semper sed erat. Nulla vehicula vitae nisl nec dignissim. Curabitur viverra risus eu est pellentesque lobortis. Nullam egestas semper convallis.
Ut ac blandit risus, sit amet elementum ex. Donec rhoncus augue eu cursus consequat. Duis a sapien sit amet elit aliquet molestie. Mauris nec ligula viverra, ornare dolor vel, malesuada nisl. Proin gravida dolor justo, sit amet tempus justo consectetur ut. Aenean malesuada iaculis tortor ac varius. Phasellus ultrices purus nisi, eu rutrum felis bibendum id. Phasellus enim dui, ultrices sed massa vel, euismod bibendum eros. Duis quis auctor augue, eget pellentesque velit. In a est at neque dignissim pellentesque et tempus sem. Nulla et leo diam.
</p>
<div class="title" id="two">Title two</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec cursus dolor id ullamcorper tempor. Donec ut ullamcorper tellus. Etiam vel rhoncus urna. Aenean augue nulla, congue a orci at, imperdiet vehicula eros. Aenean ornare nibh ut leo faucibus fringilla. Quisque varius ut ipsum egestas feugiat. Mauris id nisl ultrices, consectetur mauris in, consectetur mi. Sed sit amet dolor urna. Nullam nec enim gravida, pulvinar lacus ut, volutpat nibh. Quisque commodo eu tortor ac dictum. Vivamus sodales risus sed blandit vulputate. Proin elit erat, varius non tincidunt ut, semper sed erat. Nulla vehicula vitae nisl nec dignissim. Curabitur viverra risus eu est pellentesque lobortis. Nullam egestas semper convallis.
Ut ac blandit risus, sit amet elementum ex. Donec rhoncus augue eu cursus consequat. Duis a sapien sit amet elit aliquet molestie. Mauris nec ligula viverra, ornare dolor vel, malesuada nisl. Proin gravida dolor justo, sit amet tempus justo consectetur ut. Aenean malesuada iaculis tortor ac varius. Phasellus ultrices purus nisi, eu rutrum felis bibendum id. Phasellus enim dui, ultrices sed massa vel, euismod bibendum eros. Duis quis auctor augue, eget pellentesque velit. In a est at neque dignissim pellentesque et tempus sem. Nulla et leo diam.
</p>
<div class="title" id="three">Title three</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec cursus dolor id ullamcorper tempor. Donec ut ullamcorper tellus. Etiam vel rhoncus urna. Aenean augue nulla, congue a orci at, imperdiet vehicula eros. Aenean ornare nibh ut leo faucibus fringilla. Quisque varius ut ipsum egestas feugiat. Mauris id nisl ultrices, consectetur mauris in, consectetur mi. Sed sit amet dolor urna. Nullam nec enim gravida, pulvinar lacus ut, volutpat nibh. Quisque commodo eu tortor ac dictum. Vivamus sodales risus sed blandit vulputate. Proin elit erat, varius non tincidunt ut, semper sed erat. Nulla vehicula vitae nisl nec dignissim. Curabitur viverra risus eu est pellentesque lobortis. Nullam egestas semper convallis.
Ut ac blandit risus, sit amet elementum ex. Donec rhoncus augue eu cursus consequat. Duis a sapien sit amet elit aliquet molestie. Mauris nec ligula viverra, ornare dolor vel, malesuada nisl. Proin gravida dolor justo, sit amet tempus justo consectetur ut. Aenean malesuada iaculis tortor ac varius. Phasellus ultrices purus nisi, eu rutrum felis bibendum id. Phasellus enim dui, ultrices sed massa vel, euismod bibendum eros. Duis quis auctor augue, eget pellentesque velit. In a est at neque dignissim pellentesque et tempus sem. Nulla et leo diam.
</p>
<div class="title" id="four">Title four</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec cursus dolor id ullamcorper tempor. Donec ut ullamcorper tellus. Etiam vel rhoncus urna. Aenean augue nulla, congue a orci at, imperdiet vehicula eros. Aenean ornare nibh ut leo faucibus fringilla. Quisque varius ut ipsum egestas feugiat. Mauris id nisl ultrices, consectetur mauris in, consectetur mi. Sed sit amet dolor urna. Nullam nec enim gravida, pulvinar lacus ut, volutpat nibh. Quisque commodo eu tortor ac dictum. Vivamus sodales risus sed blandit vulputate. Proin elit erat, varius non tincidunt ut, semper sed erat. Nulla vehicula vitae nisl nec dignissim. Curabitur viverra risus eu est pellentesque lobortis. Nullam egestas semper convallis.
Ut ac blandit risus, sit amet elementum ex. Donec rhoncus augue eu cursus consequat. Duis a sapien sit amet elit aliquet molestie. Mauris nec ligula viverra, ornare dolor vel, malesuada nisl. Proin gravida dolor justo, sit amet tempus justo consectetur ut. Aenean malesuada iaculis tortor ac varius. Phasellus ultrices purus nisi, eu rutrum felis bibendum id. Phasellus enim dui, ultrices sed massa vel, euismod bibendum eros. Duis quis auctor augue, eget pellentesque velit. In a est at neque dignissim pellentesque et tempus sem. Nulla et leo diam.
</p>
<div class="title" id="five">Title five</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec cursus dolor id ullamcorper tempor. Donec ut ullamcorper tellus. Etiam vel rhoncus urna. Aenean augue nulla, congue a orci at, imperdiet vehicula eros. Aenean ornare nibh ut leo faucibus fringilla. Quisque varius ut ipsum egestas feugiat. Mauris id nisl ultrices, consectetur mauris in, consectetur mi. Sed sit amet dolor urna. Nullam nec enim gravida, pulvinar lacus ut, volutpat nibh. Quisque commodo eu tortor ac dictum. Vivamus sodales risus sed blandit vulputate. Proin elit erat, varius non tincidunt ut, semper sed erat. Nulla vehicula vitae nisl nec dignissim. Curabitur viverra risus eu est pellentesque lobortis. Nullam egestas semper convallis.
Ut ac blandit risus, sit amet elementum ex. Donec rhoncus augue eu cursus consequat. Duis a sapien sit amet elit aliquet molestie. Mauris nec ligula viverra, ornare dolor vel, malesuada nisl. Proin gravida dolor justo, sit amet tempus justo consectetur ut. Aenean malesuada iaculis tortor ac varius. Phasellus ultrices purus nisi, eu rutrum felis bibendum id. Phasellus enim dui, ultrices sed massa vel, euismod bibendum eros. Duis quis auctor augue, eget pellentesque velit. In a est at neque dignissim pellentesque et tempus sem. Nulla et leo diam.
</p>
</div>
2
Answers
Try to add this script i think it should work we need one function to check if an element is in the viewport.
The provided code is almost correct, but it fails to remove the .active class from the previous menu item when scrolling past a new title element. The issue lies in the else block of the scroll event listener, where the code attempts to remove the .active class from all elements with the class .menu li a.active.