I would like to ask how can I remove active class when scrolling? Everything works fine on desktop size, it removes the active class when I’m scrolling, even if I click on any nav menu, when I’m continue scrolling it removes the active class from that nav menu. But it gets weird on mobile device, if I’m just scrolling it works fine, but if I click (touch) on any nav menu and after that I’m scrolling then the previously clicked nav menu stay still active. You can see here https://portfolio-6t5.pages.dev/
const navItems = [ { name: "Home", link: "#", icons: "fa-house", class: "active" }, { name: "Section", link: "#project", icons: "fa-briefcase", class: "" }, { name: "About", link: "#skill", icons: "fa-book", class: "" }, { name: "Contact", link: "#about", icons: "fa-user", class: "" } ]; const nav_list = document.querySelector('.nav_list'); window.addEventListener('DOMContentLoaded', () => { let displayNav = navItems.map((item) => { return ` <li class="nav_list-item ${item.class}"> <a href="${item.link}" class="nav_link">${item.name}</a> <a href="${item.link}" class="nav_link-mobile"> <i class="fa-solid ${item.icons} nav_icon"></i> </a> </li>`; }).join(""); displayNav += ` <li class="nav_list-item hire-btn"> <a href="#hire" class="nav_link"> <button class="hire_btn" aria-label="btn">Footer</button> </a> <a href="#hire" class="nav_link-mobile"> <i class="fa-solid fa-message nav_icon"></i> </a> </li>` nav_list.innerHTML = displayNav; // Add active state to nav const nav_lists = document.querySelectorAll('.nav_list-item'); nav_lists.forEach(e => { e.addEventListener('click', () => { nav_lists.forEach(e => e.classList.remove('active')); e.classList.add('active'); }); }); }); // Add active state to nav while scrolling function addActiveOnScroll() { const navListItem = document.querySelectorAll('.nav_list-item') const btnItem = document.querySelector('.hire-btn'); const sections = document.querySelectorAll("section"); const scrollY = window.pageYOffset sections.forEach((current, key) => { const sectionHeight = current.offsetHeight, sectionTop = current.offsetTop - 100; if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { navListItem[key].classList.add('active') } else { navListItem[key].classList.remove('active') } }) if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) { navListItem.forEach(e => e.classList.remove('active')); btnItem.classList.add('active'); } } window.addEventListener('scroll', addActiveOnScroll)
Sorry, there’s some noise in the js code, but pls just ignore it
Advertisement
Answer
By looking in the inspector, it seems that on mobile, when you tap on any given menu item, it triggers the hover state. There is no .active
class to that menu item. The reason a bar is shown is because in the stylesheet you are changing the width when the menu item is active or hovered.
.nav_list-item.active a, .nav_list-item.active:after, .nav_list-item:hover:after { color: rgb(209, 209, 209); width: 100%; font-weight: 500; }