Home > database >  Changing active nav class by click and by page scroll and editing nav-item by active class
Changing active nav class by click and by page scroll and editing nav-item by active class

Time:09-26

I've completed some javascript courses but actually using it on functional web items is very humbling.

I have a navbar with same-page page links. I would like to change the nav items to active both when they are clicked, and when the page is scrolled to that section of the page. I would also like to change the innerHTML of the active nav items.

My javascript is clearly a mess. I'd like to try to at least get this solved and then it's back to practicing JS.

<div class="collapse navbar-collapse" style="background-color: #1e3d58;" id="navbarToggler">
    <ul class="navbar-nav text-center mx-auto mb-2 mb-sm-0">
        <li class="nav-item">
            <a class="nav-link" href="#home">Home</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#about">About</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#skills">Skills</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#contact">Contact</a>
        </li>
    </ul>
    <div class="d-none d-sm-flex mt-sm-2 mt-md-0 justify-content-center">
        <a class="btn btn-social-icon btn-linkedin" href="#"><i class="fab fa-2x fa-github-square"></i></a>
        <a class="btn btn-social-icon btn-linkedin" href="http://www.linkedin.com/in/"><i
                class="fab fa-2x fa-linkedin"></i></a>
    </div>
</div>
.nav-item {
  padding: 0px 2vw 0px 2vw;
}

.nav-link {
  color: #e8eef1 !important;
}

nav .fab {
  color: #e8eef1;
  margin: 0px -8px 0px -8px;
}

nav {
  max-height: 60px;
}
document.querySelector(function () {
    document.querySelector(".nav-item").click(function () {
        document.querySelector(".nav-item").each(function () {
            document.querySelector(this).querySelector("a").removeClass("active");
        });
        document.querySelector(this).querySelector("a").classList.add("active");
    });
});

document.querySelector(function () {
    for (document.querySelector(".nav-item")) {
        if document.querySelector("a").hasClass("active")
        then document.querySelector("a").innerHTML = "<"   document.querySelector('a')   "/>"
    };
});

CodePudding user response:

The js would be something like:

let navItems = document.querySelectorAll('li.nav-item a');

navItems.forEach((el) => {
  el.addEventListener('click',() => {
    if (!el.classList.contains('active') {
      navItems.forEach((others) => {
          //Remove the update to innerHTML for all of the items however you plan on doing that, I would suggest just adding or removing a class to update their style
          others.classList.remove('active');
      };
      el.classList.add('active');
    };
    
  });
});

CodePudding user response:

I was able to find a solution to this that solved all 3 problems.

  • The active class changes when nav item is clicked
  • The active class changes when page is scrolled to page section
  • The textContent of the navbar item links are changed when the a link class is active

Javascript

const sections = document.querySelectorAll('section');
const navLi = document.querySelectorAll('#navbarToggler li a')

window.addEventListener('scroll', ()=> {
    let current = "";
    sections.forEach( section => {
        const sectionTop = section.offsetTop;
        const sectionHeight = section.clientHeight;
        if(scrollY >= (sectionTop - sectionHeight/3)){
            current = section.getAttribute('id');
        }
    })
    navLi.forEach( a => {
        a.classList.remove('active');
        if(a.classList.contains(current)){
            a.classList.add('active')
        }
    })
})


window.addEventListener('scroll'||'click', ()=> {
    navLi.forEach( a => {
        const navText= a.textContent;
        if (a.classList.contains('active')){
            if(a.textContent == "Home"){
                a.textContent = "<Home/>"
            }
            if(a.textContent == "About"){
                a.textContent = "<About/>"
            }
            if(a.textContent == "Skills"){
                a.textContent = "<Skills/>"
            }
            if(a.textContent == "Contact"){
                a.textContent = "<Contact/>"
            }
        }
        else {
            if(a.textContent == "<Home/>"){
                a.textContent = "Home"
            }
            if(a.textContent == "<About/>"){
                a.textContent = "About"
            }
            if(a.textContent == "<Skills/>"){
                a.textContent = "Skills"
            }
            if(a.textContent == "<Contact/>"){
                a.textContent = "Contact"
            }
        }
        })
})

HTML

<nav class="navbar navbar-expand-md navbar-dark fixed-top" style="background-color: #1e3d58;">
        <div class=" container">
            <a class="navbar-brand" href="#home"><strong>.Vince-clicks{}</strong></a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggler"
                aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" style="background-color: #1e3d58;" id="navbarToggler">
                <ul class="navbar-nav text-center mx-auto mb-2 mb-sm-0">
                    <li class="nav-item">
                        <a class="nav-link home active" href="#home">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link about" href="#about">About</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link skills" href="#skills">Skills</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link contact" href="#contact">Contact</a>
                    </li>
                </ul>
                <div class="d-none d-sm-flex mt-sm-2 mt-md-0 justify-content-center">
                    <a class="btn btn-social-icon btn-linkedin" href="#"><i class="fab fa-2x fa-github-square"></i></a>
                    <a class="btn btn-social-icon btn-linkedin" href="http://www.linkedin.com/in/"><i
                            class="fab fa-2x fa-linkedin"></i></a>
                </div>
            </div>
        </div>
    </nav>

Each page section also has an appropriate id.

Hope this helps others who had the same issue.

  • Related