Home > Software design >  Change "active" class in navbar on scrolling - JavaScript, HTML
Change "active" class in navbar on scrolling - JavaScript, HTML

Time:07-13

So I want to change the active class in navbar whenever a user scrolls. Like, initially the Home element has active class and hence the background of Home is violet. enter image description here

But as soon as I scroll down to the About Me section, I want the background of Home in navbar to be white and that of About to be violet. enter image description here

But I'm not much experienced with JavaScript. I found a codepen in a YouTube video which showed the navbar links changing the active class on scrolling.

Here's the codepen that I got from YouTube: https://codepen.io/Web_Cifar/pen/LYRBbVE

That code snippet from YouTube:

const sections = document.querySelectorAll("section");
const navLi = document.querySelectorAll("nav .container ul li");
window.addEventListener("scroll", () => {
  let current = "";
  sections.forEach((section) => {
    const sectionTop = section.offsetTop;
    const sectionHeight = section.clientHeight;
    if (pageYOffset >= sectionTop - sectionHeight / 3) {
      current = section.getAttribute("id");
    }
  });

  navLi.forEach((li) => {
    li.classList.remove("active");
    if (li.classList.contains(current)) {
      li.classList.add("active");
    }
  });
});
@import url("https://fonts.googleapis.com/css2?family=Roboto Mono&display=swap");
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html {
  font-family: "Roboto Mono";
  font-size: 24px;
  scroll-behavior: smooth;
}

section {
  height: 100vh;
  width: 100%;
  background-color: gray;
  display: flex;
  align-items: center;
  justify-content: center;
  text-transform: uppercase;
}

#home {
  background-color: royalblue;
}

#about {
  background-color: aquamarine;
}

#footer {
  background-color: crimson;
}

nav {
  position: sticky;
  top: 0;
  background-color: white;
}

nav .container {
  width: 90%;
  max-width: 1000px;
  margin: 0 auto;
  text-align: center;
  padding: 10px;
}

nav .container ul li {
  display: inline-block;
}

nav .container ul li a {
  display: inline-block;
  text-decoration: none;
  padding: 10px 20px;
  color: black;
}

nav .container ul li.active {
  background-color: crimson;
  transition: 0.3s ease background-color;
}

nav .container ul li.active a {
  color: rgb(255, 255, 255);
}


/* ********************* */


/* This Code is for only the floating card in right bottom corner */


/* ********************** */

@import url("https://fonts.googleapis.com/css2?family=Roboto Mono&display=swap");
* {
  padding: 0;
  margin: 0;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

a {
  padding: 0;
  margin: 0;
  color: var(--color-4);
  text-decoration: none;
}

#webCifar-sidebox {
  position: fixed;
  right: 0px;
  bottom: 0px;
  overflow-x: clip;
  width: 300px;
  font-size: 16px;
}

#webCifar-sidebox p {
  padding: 0;
  margin: 0;
}

#webCifar {
  --color-1: #17bcb4;
  --color-2: #24252a;
  --color-3: #244044;
  --color-4: #f3f8f7;
  background: var(--color-2);
  display: inline-block;
  color: var(--color-4);
  padding: 10px 17px;
  border-radius: 6px;
  font-family: "Roboto Mono", monospace;
  text-align: center;
  position: absolute;
  right: 5px;
  bottom: 5px;
  -webkit-transform: translateX(calc(100%   5px));
  transform: translateX(calc(100%   5px));
  -webkit-transition: 0.5s ease-out transform;
  transition: 0.5s ease-out transform;
  z-index: 4;
}

#webCifar.active {
  -webkit-transform: translateX(0);
  transform: translateX(0);
}

#webCifar .logo {
  font-size: 25px;
}

#webCifar .author {
  margin-top: 10px;
  margin-bottom: 20px;
}

#webCifar .author span {
  background-color: var(--color-3);
  padding: 3px;
  border-radius: 4px;
}

#webCifar .items {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: start;
  -ms-flex-align: start;
  align-items: start;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
}

#webCifar .item {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  gap: 10px;
  padding: 5px;
  border-radius: 4px;
  text-align: left;
}

#webCifar .item:hover {
  background-color: var(--color-3);
}

#webCifar svg {
  max-width: 20px;
}

#webCifar .close {
  position: absolute;
  display: inline-block;
  height: 30px;
  width: 30px;
  right: 5px;
  top: 5px;
  padding: 5px;
  background-color: var(--color-3);
  border-radius: 50%;
  font-size: 20px;
  cursor: pointer;
}

#webCifar-icon {
  --color-2: #24252a;
  --color-3: #244044;
  font-family: "Roboto Mono", monospace;
  text-align: left;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  background-color: var(--color-2);
  color: white;
  width: -webkit-fit-content;
  width: -moz-fit-content;
  width: fit-content;
  padding: 5px;
  border-radius: 4px;
  gap: 5px;
  margin: 5px;
  cursor: pointer;
  z-index: 1;
  position: relative;
  right: -27%;
  border: 1px solid #ffffff7d;
}

#webCifar-icon svg {
  max-width: 20px;
}
<nav>
  <div >
    <ul>
      <li ><a href="#home">Home</a></li>
      <li ><a href="#about">About</a></li>
      <li ><a href="#contact">Contact</a></li>
      <li ><a href="#footer">Footer</a></li>
    </ul>
  </div>
</nav>
<section id="home">
  <h1>Home</h1>
</section>
<section id="about">
  <h1>About</h1>
</section>
<section id="contact">
  <h1>Contact</h1>
</section>
<section id="footer">
  <h1>Footer</h1>
</section>

<!-- *******************   -->
<!--  !!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!--  This Code is for only the floating card in right bottom corner -->
<!-- ********************  -->

<div id="webCifar-sidebox">
  <div id="webCifar">
    <h2 >Web Cifar</h2>
    <p >Coded By <span>Shaif Arfan</span> </p>
    <div >
      <a href="https://www.youtube.com/channel/UCdxaLo9ALJgXgOUDURRPGiQ" target="_blank" >
        <svg title="watch how we made this" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
          <path d="M10 12a2 2 0 100-4 2 2 0 000 4z" />
          <path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd" />
        </svg>
        <p>Watch how we made this.
        </p>
      </a>
      <a href="https://webcifar.com" target="_blank" >
        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
        </svg>
        <p>https://webcifar.com</p>
      </a>

    </div>
    <div >
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
      </svg>
    </div>
  </div>
  <div id="webCifar-icon">
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
    </svg>
    <p>Info About the pen</p>
  </div>
</div>

This is my snippet:

const sections = document.querySelectorAll("section");
const navLi = document.querySelectorAll(".navbar .nav-container a");
window.addEventListener("scroll", () => {
  let current = "";
  sections.forEach((section) => {
    const sectionTop = section.offsetTop;
    const sectionHeight = section.clientHeight;
    if (pageYOffset >= sectionTop - sectionHeight / 3) {
      current = section.getAttribute("id");
    }
  });

  navLi.forEach((li) => {
    li.classList.remove("active");
    if (li.classList.contains(current)) {
      li.classList.add("active");
    }
  });
});
@import url('https://fonts.googleapis.com/css2?family=Comic Neue:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Nunito Sans:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap');
@font-face {
  font-family: "neoneon";
  src: url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.ttf) format('truetype'), /* ../../<repo-name>Fonts/<font-name>.<format> is for using custom fonts on github*/
  url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.eot) format('embedded-opentype'), url(./Assets/Fonts/Neoneon/Neoneon.woff) format('woff'), /* ../Fonts/<font-name>.<format> is for using locally and on live server */
  url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.svg) format('svg'), url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.woff2) format('woff2');
  font-weight: normal;
  font-style: normal;
}

html,
body {
  height: 100%;
  margin: 0;
  max-width: 100vw;
  overflow-x: hidden;
}

body {
  scroll-behavior: smooth;
  font-family: 'Nunito Sans', sans-serif;
}

::-webkit-scrollbar {
  width: 3px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
}

::-webkit-scrollbar-thumb {
  background: rgba(225, 0, 225, 0.469);
}

::-webkit-scrollbar-thumb:hover {
  background: rgb(225, 0, 225);
}

.navbar {
  overflow: hidden;
  background-color: white;
  box-shadow: 0 2px #88888853;
  width: 100vw;
  position: fixed;
  z-index: 2;
}

.nav-container {
  float: right;
  width: 35%;
  display: flex;
  justify-content: space-around;
}

.nav-container a {
  padding: 16px;
  color: black;
  text-decoration: none;
}

.nav-container .active {
  background-color: rgba(225, 0, 225, 0.469);
}

.nav-container a:hover:not(.active) {
  background-color: rgba(0, 0, 0, 0.265);
}

#brief {
  width: 100vw;
  display: flex;
  justify-content: center;
  padding: 140px 0 140px;
  background-image: url('./Assets/images/bg.jpg');
  background-repeat: no-repeat;
  background-size: cover;
}

#brief-container {
  width: 40%;
  display: flex;
  flex-direction: column;
}

#brief-container .brief-pic {
  display: flex;
  justify-content: center;
  z-index: 1;
}

#brief-container img {
  border: 3px solid white;
  border-radius: 50%;
  width: 150px;
}

#brief-container .brief-text {
  background-color: white;
  gap: 20px;
  text-align: center;
  display: flex;
  flex-direction: column;
  margin: -70px;
  padding: 90px 30px 40px;
}

#brief-container .brief-name {
  font-family: neoneon;
  font-size: 30px;
  font-style: italic;
  font-weight: bold;
}

#brief-container .brief-name span,
#about .about-title span {
  color: rgb(225, 0, 225);
}

#brief-container .brief-description {
  font-family: 'Comic Neue', cursive;
  font-size: 20px;
}

#about {
  width: 70vw;
  display: flex;
  flex-direction: column;
  margin: 30px auto;
  padding: 50px 0;
  gap: 20px;
  top: 0;
}

#about .about-title {
  font-family: neoneon;
  font-size: 40px;
  font-weight: bold;
}

#about .about-content {
  text-align: justify;
  font-size: 20px;
}

#about,
#projects,
#contact {
  scroll-margin-top: 50px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="./style.css">
  <script src="./script.js"></script>
  <title>Web</title>
</head>

<body>
  <nav >
    <div >
      <a  href="index.html">Home</a>
      <a  href="#about">About</a>
      <a  href="#">Projects</a>
      <a  href="#">Contact</a>
    </div>
  </nav>
  <section id="brief">
    <div id="brief-container">
      <div >
        <img src="./Assets/images/pfp.jpg" alt="profile picture">
      </div>
      <div >
        <div >
          Web <span>Web</span>
        </div>
        <div >
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Minus molestiae sit earum consectetur quae id eius esse magnam hic, cumque, consequuntur numquam possimus doloremque rem vitae. Illo exercitationem accusantium laboriosam.
        </div>
      </div>
    </div>
  </section>
  <section id="about">
    <div >
      About <span>Me</span>
    </div>
    <div >
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae ab consequatur, beatae architecto quidem sequi doloremque quam animi quasi est. Placeat impedit facere reiciendis ab deleniti, dolorum accusamus illo libero. Lorem ipsum dolor sit amet, consectetur
      adipisicing elit. Recusandae, numquam quidem. Ratione qui neque esse aliquid quod impedit hic facilis aut, perspiciatis suscipit exercitationem sunt. Repudiandae ex accusamus blanditiis. Sed.</div>
  </section>
</body>

</html>

So basically my HTML is like:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<nav >
    <div >
      <a  href="#brief">Home</a>
      <a  href="#about">About</a>
      <a  href="#">Contact</a>
    </div>
  </nav>

  <section id="brief">
    Lorem, ipsum dolor sit amet consectetur adipisicing elit. Aliquam facere unde itaque ea, minus commodi voluptate in a quibusdam minima dolores veniam, consectetur, quam eveniet architecto esse aut culpa iure!
  </section>
  <section id="about">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet ipsa tenetur sapiente magnam, reprehenderit odit ex. Delectus laborum omnis laudantium ea recusandae nihil, sequi, atque voluptatem tenetur inventore vero voluptatibus.
  </section>
</body>
</html>

And JavaScript is:

const sections = document.querySelectorAll("section");
const navLi = document.querySelectorAll(".navbar .nav-container a");
window.addEventListener("scroll", () => {
  let current = "";
  sections.forEach((section) => {
    const sectionTop = section.offsetTop;
    const sectionHeight = section.clientHeight;
    if (pageYOffset >= sectionTop - sectionHeight / 3) {
      current = section.getAttribute("id");
    }
  });

  navLi.forEach((li) => {
    li.classList.remove("active");
    if (li.classList.contains(current)) {
      li.classList.add("active");
    }
  });
});

I've looked a lot but I'm unable to find a solution.

Please help me find and correct the error in my code.

CodePudding user response:

Remove overflow-x: hidden; from html and body.

const sections = document.querySelectorAll("section");
const navLi = document.querySelectorAll(".navbar .nav-container a");
window.addEventListener("scroll", () => {
  let current = "";
  sections.forEach((section) => {
    const sectionTop = section.offsetTop;
    const sectionHeight = section.clientHeight;
    if (pageYOffset >= sectionTop - sectionHeight / 3) {
      current = section.getAttribute("id");
    }
  });

  navLi.forEach((li) => {
    li.classList.remove("active");
    if (li.classList.contains(current)) {
      li.classList.add("active");
    }
  });
});
@import url('https://fonts.googleapis.com/css2?family=Comic Neue:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Nunito Sans:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap');
@font-face {
  font-family: "neoneon";
  src: url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.ttf) format('truetype'), /* ../../<repo-name>Fonts/<font-name>.<format> is for using custom fonts on github*/
  url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.eot) format('embedded-opentype'), url(./Assets/Fonts/Neoneon/Neoneon.woff) format('woff'), /* ../Fonts/<font-name>.<format> is for using locally and on live server */
  url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.svg) format('svg'), url(../personal-portfolio/Assets/Fonts/Neoneon/Neoneon.woff2) format('woff2');
  font-weight: normal;
  font-style: normal;
}

html,
body {
  height: 100%;
  margin: 0;
  max-width: 100vw;
  /* overflow-x: hidden; */
}

body {
  scroll-behavior: smooth;
  font-family: 'Nunito Sans', sans-serif;
}

::-webkit-scrollbar {
  width: 3px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
}

::-webkit-scrollbar-thumb {
  background: rgba(225, 0, 225, 0.469);
}

::-webkit-scrollbar-thumb:hover {
  background: rgb(225, 0, 225);
}

.navbar {
  overflow: hidden;
  background-color: white;
  box-shadow: 0 2px #88888853;
  width: 100vw;
  position: fixed;
  z-index: 2;
}

.nav-container {
  float: right;
  width: 35%;
  display: flex;
  justify-content: space-around;
}

.nav-container a {
  padding: 16px;
  color: black;
  text-decoration: none;
}

.nav-container .active {
  background-color: rgba(225, 0, 225, 0.469);
}

.nav-container a:hover:not(.active) {
  background-color: rgba(0, 0, 0, 0.265);
}

#brief {
  width: 100vw;
  display: flex;
  justify-content: center;
  padding: 140px 0 140px;
  background-image: url('./Assets/images/bg.jpg');
  background-repeat: no-repeat;
  background-size: cover;
}

#brief-container {
  width: 40%;
  display: flex;
  flex-direction: column;
}

#brief-container .brief-pic {
  display: flex;
  justify-content: center;
  z-index: 1;
}

#brief-container img {
  border: 3px solid white;
  border-radius: 50%;
  width: 150px;
}

#brief-container .brief-text {
  background-color: white;
  gap: 20px;
  text-align: center;
  display: flex;
  flex-direction: column;
  margin: -70px;
  padding: 90px 30px 40px;
}

#brief-container .brief-name {
  font-family: neoneon;
  font-size: 30px;
  font-style: italic;
  font-weight: bold;
}

#brief-container .brief-name span,
#about .about-title span {
  color: rgb(225, 0, 225);
}

#brief-container .brief-description {
  font-family: 'Comic Neue', cursive;
  font-size: 20px;
}

#about {
  width: 70vw;
  display: flex;
  flex-direction: column;
  margin: 30px auto;
  padding: 50px 0;
  gap: 20px;
  top: 0;
}

#about .about-title {
  font-family: neoneon;
  font-size: 40px;
  font-weight: bold;
}

#about .about-content {
  text-align: justify;
  font-size: 20px;
}

#about,
#projects,
#contact {
  scroll-margin-top: 50px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="./style.css">
  <script src="./script.js"></script>
  <title>Web</title>
</head>

<body>
  <nav >
    <div >
      <a  href="index.html">Home</a>
      <a  href="#about">About</a>
      <a  href="#">Projects</a>
      <a  href="#">Contact</a>
    </div>
  </nav>
  <section id="brief">
    <div id="brief-container">
      <div >
        <img src="./Assets/images/pfp.jpg" alt="profile picture">
      </div>
      <div >
        <div >
          Web <span>Web</span>
        </div>
        <div >
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Minus molestiae sit earum consectetur quae id eius esse magnam hic, cumque, consequuntur numquam possimus doloremque rem vitae. Illo exercitationem accusantium laboriosam.
        </div>
      </div>
    </div>
  </section>
  <section id="about">
    <div >
      About <span>Me</span>
    </div>
    <div >
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae ab consequatur, beatae architecto quidem sequi doloremque quam animi quasi est. Placeat impedit facere reiciendis ab deleniti, dolorum accusamus illo libero. Lorem ipsum dolor sit amet, consectetur
      adipisicing elit. Recusandae, numquam quidem. Ratione qui neque esse aliquid quod impedit hic facilis aut, perspiciatis suscipit exercitationem sunt. Repudiandae ex accusamus blanditiis. Sed.</div>
  </section>
</body>

</html>

  • Related