![Active Active]()
const links = document.querySelectorAll('.links');const sections = document.querySelectorAll('section');function changeLinkState() { let index = sections.length; while(--index && window.scrollY + 50 < sections[index].offsetTop) {} links.forEach((link) => link.classList.remove('active')); links[index].classList.add('active');}changeLinkState();window.addEventListener('scroll', changeLinkState); nav { position: fixed; top: 0; right: 0; width: 10em;}section { height: 100vh; margin: 1em 0; background: gold;}.active { background: silver;} <nav> <ul> <li id="linkTop" class="links"> <a href="#top">Home</a> </li> <li id="linkAbout" class="links"> <a href="#about">About Us</a> </li> <li id="linkServices" class="links"> <a href="#services">Services</a> </li> <li id="linkClients" class="links"> <a href="#clients">Clients</a> </li> <li id="linkContact" class="links"> <a href="#contact">Contact</a> </li> </ul></nav><section> Home</section><section> About Us</section><section> Services</section><section> Clients</section><section> Contact</section> I'm trying to ditch jQuery from my upcoming projects. I found a way to create a sticky nav on scroll with pure Vanilla JS, and wanted the links on my navigation to change their active state as they reach the corresponding sections.Below is the working solution I came up with, but I'm sure that the code can be improved to work programmatically without having to select and create conditions for each element.I'm also using a lot of different selectors, and I'm pretty sure there must be a way to improve that, maybe using querySelectorAll and adding an eventListener in a forEach loop, but I can't get that to work either. Thanks for your help!// select linksconst allLinks = document.querySelectorAll('header nav ul li');const linkTop = document.querySelector('#linkTop');const linkAbout = document.querySelector('#linkAbout');const linkServices = document.querySelector('#linkServices');const linkClients = document.querySelector('#linkClients');const linkContact = document.querySelector('#linkContact');// select sectionsconst sectionTop = document.querySelector('#top');const sectionAbout = document.querySelector('#about');const sectionServices = document.querySelector('#services');const sectionClients = document.querySelector('#clients');const sectionContact = document.querySelector('#contact');function changeLinkState() { // home if (window.scrollY >= sectionTop.offsetTop) { allLinks.forEach(link => { link.classList.remove('active'); }); linkTop.classList.add('active'); } // about if (window.scrollY >= sectionAbout.offsetTop) { allLinks.forEach(link => { link.classList.remove('active'); }); linkAbout.classList.add('active'); } // services if (window.scrollY >= sectionServices.offsetTop) { allLinks.forEach(link => { link.classList.remove('active'); }); linkServices.classList.add('active'); } clients if (window.scrollY >= sectionClients.offsetTop) { allLinks.forEach(link => { link.classList.remove('active'); }); linkClients.classList.add('active'); } contact if (window.scrollY >= sectionContact.offsetTop) { allLinks.forEach(link => { link.classList.remove('active'); }); linkContact.classList.add('active'); }}window.addEventListener('scroll', changeLinkState);<nav> <ul> <li id="linkTop"> <a href="#top">Home</a> </li> <li id="linkAbout"> <a href="#about">About Us</a> </li> <li id="linkServices"> <a href="#services">Services</a> </li> <li id="linkClients"> <a href="#clients">Clients</a> </li> <li id="linkContact"> <a href="#contact">Contact</a> </li> </ul></nav>Thanks a lot! 解决方案 You can get all sections and links using document.querySelectorAll(). On scroll iterate the list of section from last to first, until you find one that matches. Then remove the .active class from all links, and add it to the link at the active index.Note: You should use throttling to prevent the calling of changeLinkState multiple times in a second. Another option is to use the Intersection Observer API.const links = document.querySelectorAll('.links');const sections = document.querySelectorAll('section');function changeLinkState() { let index = sections.length; while(--index && window.scrollY + 50 < sections[index].offsetTop) {} links.forEach((link) => link.classList.remove('active')); links[index].classList.add('active');}changeLinkState();window.addEventListener('scroll', changeLinkState);nav { position: fixed; top: 0; right: 0; width: 10em;}section { height: 100vh; margin: 1em 0; background: gold;}.active { background: silver;}<nav> <ul> <li id="linkTop" class="links"> <a href="#top">Home</a> </li> <li id="linkAbout" class="links"> <a href="#about">About Us</a> </li> <li id="linkServices" class="links"> <a href="#services">Services</a> </li> <li id="linkClients" class="links"> <a href="#clients">Clients</a> </li> <li id="linkContact" class="links"> <a href="#contact">Contact</a> </li> </ul></nav><section> Home</section><section> About Us</section><section> Services</section><section> Clients</section><section> Contact</section> 这篇关于Vanilla JS在滚动重构时更改链接的活动状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-27 14:26