0

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

Surge
  • 81
  • 8

1 Answers1

1

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;
}
Khalil
  • 1,495
  • 6
  • 14
  • Sorry, but I still don't get it. It removes and adds properly the active class when I'm scrolling, but the previously clicked menu item is shown like it was "active". The .nav_list-item.active:after.. with: 100% is needed on desktop size, when you hover on nav item – Surge Aug 19 '22 at 14:49
  • 1
    That's because the menu item is in hover state. Once you tap on an element on mobile, that element's hover state becomes active until you tap on another element. Scrolling does not change the hover state of the last tapped element. – Khalil Aug 19 '22 at 14:51
  • Hm, I think I'm getting to understand it :D but how can I remove the hover state in this case? – Surge Aug 19 '22 at 15:00
  • 1
    You can check the following question: https://stackoverflow.com/questions/23885255/how-to-remove-ignore-hover-css-style-on-touch-devices – Khalil Aug 19 '22 at 15:05