所以我想在用户滚动时,更改导航栏中的活动类。例如,最初Home元素具有活动类,因此Home的背景是violet。
但是,当我向下滚动到“关于我”部分时,我希望导航栏中Home的背景为白色,而About的背景为紫色。
但我对JavaScript没有太多经验。我在YouTube video中发现了一个codepen,它显示导航栏链接在滚动时改变了活动类。
这是我从YouTube上得到的代码:https://codepen.io/Web_Cifar/pen/LYRBbVE
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 class="container">
<ul>
<li class="home active"><a href="#home">Home</a></li>
<li class="about"><a href="#about">About</a></li>
<li class="contact"><a href="#contact">Contact</a></li>
<li class="footer"><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 class="logo">Web Cifar</h2>
<p class="author">Coded By <span>Shaif Arfan</span> </p>
<div class="items">
<a href="https://www.youtube.com/channel/UCdxaLo9ALJgXgOUDURRPGiQ" target="_blank" class="item youtubeLink">
<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" class="item">
<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 class="close">
<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>
这是我的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 class="navbar">
<div class="nav-container">
<a class="brief active" href="index.html">Home</a>
<a class="about" href="#about">About</a>
<a class="project" href="#">Projects</a>
<a class="contact" href="#">Contact</a>
</div>
</nav>
<section id="brief">
<div id="brief-container">
<div class="brief-pic">
<img src="./Assets/images/pfp.jpg" alt="profile picture">
</div>
<div class="brief-text">
<div class="brief-name">
Web <span>Web</span>
</div>
<div class="brief-description">
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 class="about-title">
About <span>Me</span>
</div>
<div class="about-content">
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>
所以我的HTML基本上是这样的:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<a class="brief active" href="#brief">Home</a>
<a class="about" href="#about">About</a>
<a class="contact" 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>
JavaScript是:
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");
}
});
});
我找了很多,但我找不到解决办法。
请帮助我找到并纠正代码中的错误。
2条答案
按热度按时间wj8zmpe11#
从
html
和body
中删除overflow-x: hidden;
。4xrmg8kj2#
最近,回到这个项目,遇到了@Gerard提供的解决方案的问题。上次我没有注意到这一点,但是活动类甚至在特定部分出现在屏幕上之前就被更改了。所以我更新如下:
网站Map
这将使截面类保持活动状态,直到下面或上面的截面类占据屏幕的大部分。
看看它在我的personal portfolio上的实现。
查看我的github repo上的完整代码。