粘性导航无法正常工作,这是怎么回事?
Sticky nav isn't working, what's going on?
所以我试图让我的导航栏在人们滚动时保持在页面顶部,但它不想工作。出于某种原因,控制台不断抛出错误,指出 classList.remove()
属性未定义。但与此同时,当我移除它们时,导航栏不会粘住。
如果有帮助,我构建了两个导航栏。一个用于 mobile/tablet,另一个用于台式机。
这是怎么回事?
// ---------------------------------------- GLOBAL VARIABLES
const mobileNavbar = document.getElementsByClassName("mobile-navbar");
const desktopNavbar = document.getElementsByClassName("desktop-navbar");
const stickyDesktop = desktopNavbar.offsetTop;
const stickyMobile = mobileNavbar.offsetTop;
window.onscroll = function () {
stickyNav()
};
function stickyNav() {
if (window.pageYOffset >= stickyDesktop || window.pageYOffset >= stickyMobile) {
desktopNavbar.classList.add("sticky");
mobileNavbar.classList.add("sticky");
}
else {
desktopNavbar.classList.remove("sticky");
mobileNavbar.classList.remove("sticky");
}
}
// ---------------------------------------- DESKTOP NAVBAR
document.addEventListener('click', e => {
const isDropdownButton = e.target.matches("[data-dropdown-button]")
if (!isDropdownButton && e.target.closest('[data-dropdown]') != null) return
let currentDropdown
if (isDropdownButton) {
currentDropdown = e.target.closest('[data-dropdown]')
currentDropdown.classList.toggle('active')
}
document.querySelectorAll('[data-dropdown].active').forEach(dropdown => {
if (dropdown === currentDropdown) return
dropdown.classList.remove('active')
})
})
// ---------------------------------------- MOBILE NAVBAR
const toggleButton = document.getElementsByClassName('fa-bars')[0]
const mobileNavBar = document.getElementsByClassName('mobile-navbar-links')[0]
toggleButton.addEventListener('click', () => {
mobileNavBar.classList.toggle('active')
})
* {
box-sizing: border-box;
}
a {
text-decoration: none;
color: #000;
}
body {
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
}
.sticky {
position: fixed;
top: 0;
width: 100%;
}
.sticky + body {
padding-top: 60px;
}
.scrollDown {
position: absolute;
top: 93%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.scrollDown a {
text-decoration: none;
}
.scrollDown p {
margin: 0;
font-family: 'Nunito', sans-serif;
font-size: 20px;
color: #fff;
}
.fa-chevron-down,
.fa-chevron-up {
width: 50px;
height: 50px;
font-size: 32px;
color: #fff;
;
}
.scrollDown:hover {
transition: .2s ease;
}
@media screen and (max-width: 600px) {
/* ------------------------------- MOBILE NAVBAR */
.desktop-navbar {
display: none;
}
.mobile-navbar {
display: flex;
overflow: hidden;
justify-content: space-between;
align-items: center;
background-color: #333;
color: #fff;
}
.mobile-brand-title {
font-size: 1.5rem;
margin: .5rem;
}
.mobile-navbar-links ul {
margin: 0;
padding: 0;
display: flex;
}
.mobile-navbar-links li {
list-style: none;
}
.mobile-navbar-links li a {
color: #fff;
padding: 1rem;
display: block;
}
.mobile-navbar-links li:hover {
background-color: #555;
}
.mobile-navbar .fa-bars {
position: absolute;
display: none;
flex-direction: column;
justify-content: space-between;
top: .75rem;
right: 1rem;
color: #fff;
width: 1rem;
height: 1rem;
cursor: pointer;
}
.mobile-navbar .fa-bars {
display: flex;
}
.mobile-navbar-links {
display: none;
width: 100%;
}
.mobile-navbar {
flex-direction: column;
align-items: flex-start;
}
.mobile-navbar-links ul {
width: 100%;
flex-direction: column;
}
.mobile-navbar-links li {
text-align: center;
}
.mobile-navbar-links.active {
display: flex;
}
}
@media screen and (min-width: 601px) {
/* ------------------------------- DESKTOP NAVBAR */
.mobile-navbar {
display: none;
}
.desktop-navbar {
background-color: #f3f3f3;
overflow: hidden;
display: flex;
align-items: baseline;
padding: .5rem;
gap: 1rem;
}
.link {
background: none;
border: none;
text-decoration: none;
color: #777;
font-family: inherit;
font-size: inherit;
cursor: pointer;
padding: 0;
}
.dropdown.active+.link,
.link:hover {
color: #000;
}
.dropdown {
position: relative;
}
.dropdown-menu {
position: absolute;
left: 0;
top: calc(100% + .25rem);
background-color: #fff;
padding: .75rem;
border-radius: .25rem;
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.3);
z-index: 1000;
opacity: 0;
pointer-events: none;
transition: opacity 150ms ease, transform 150ms ease;
transform: translateY(-10px);
}
.dropdown.active>.link+.dropdown-menu {
opacity: 1;
transform: translateY(0px);
pointer-events: auto;
}
.information-grid {
display: grid;
grid-template-columns: repeat(2, max-content);
gap: 2rem;
}
.dropdown-links {
display: flex;
flex-direction: column;
gap: .25rem;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Fox Bank</title>
<!-- Meta tags -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Links/Styles -->
<link rel="stylesheet" href="styles/styles.css">
<link rel="stylesheet" href="styles/normalize.css">
<link rel="stylesheet" href="styles/responsive.css">
<link rel="stylesheet" href="styles/flickity.min.css" media="screen">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
<!-- Javascript -->
<script src="https://kit.fontawesome.com/8821130486.js" crossorigin="anonymous"></script>
<script src="js/jquery.js" defer></script>
<script src="js/app.js" async defer></script>
<script src="js/flickity.min.js" defer></script>
</head>
<body>
<!--------------------- DESKTOP NAVBAR -->
<!--------------------------------------->
<div class="desktop-navbar">
<div>
<a href="#">
<h1>Big Bank</h1>
</a>
</div>
<div class="dropdown" data-dropdown>
<button class="link" data-dropdown-button>About</button>
<div class="dropdown-menu information-grid">
<div>
<div class="dropdown-heading">Meet Our Team</div>
<div class="dropdown-links">
<a href="#" class="link">Staff</a>
<a href="#" class="link">Board of Directors</a>
</div>
</div>
<div>
<div class="dropdown-heading">Our History</div>
<div class="dropdown-links">
<a href="#" class="link">Overview</a>
<a href="#" class="link">Future</a>
</div>
</div>
<div>
<div class="dropdown-heading">Blog</div>
<div class="dropdown-links">
<a href="#" class="link">Latest Posts</a>
<a href="#" class="link">In The Community</a>
<a href="#" class="link">Security & Fraud Prevention</a>
<a href="#" class="link">National & International Money</a>
</div>
</div>
<div>
<div class="dropdown-heading">Contact Us</div>
<div class="dropdown-links">
<a href="#" class="link">Support Center</a>
<a href="#" class="link">Phone & Mailing Information</a>
<a href="#" class="link">Social Media</a>
</div>
</div>
</div>
</div>
<div class="dropdown" data-dropdown>
<button class="link" data-dropdown-button>Products</button>
<div class="dropdown-menu information-grid">
<div>
<div class="dropdown-heading">Checking</div>
<div class="dropdown-links">
<a href="#" class="link">Basic Checking</a>
<a href="#" class="link">Teens Checking</a>
<a href="#" class="link">Prime Checking</a>
<a href="#" class="link">Elite Checking</a>
</div>
</div>
<div>
<div class="dropdown-heading">Savings</div>
<div class="dropdown-links">
<a href="#" class="link">Basic Savings</a>
<a href="#" class="link">Teens Savings</a>
<a href="#" class="link">Prime Savings</a>
<a href="#" class="link">Elite Savings</a>
</div>
</div>
<div>
<div class="dropdown-heading">Borrow</div>
<div class="dropdown-links">
<a href="#" class="link">Personal Loans</a>
<a href="#" class="link">Auto Loans</a>
<a href="#" class="link">Credit Cards</a>
<a href="#" class="link">Mortgage</a>
<a href="#" class="link">Shark Loans</a>
</div>
</div>
<div>
<div class="dropdown-heading">Retirement</div>
<div class="dropdown-links">
<a href="#" class="link">Traditional IRA</a>
<a href="#" class="link">Roth IRA</a>
<a href="#" class="link">Self Employment IRA</a>
</div>
</div>
</div>
</div>
<a href="#"><button>Login</button></a>
</div>
<!---------------------- MOBILE NAVBAR -->
<!--------------------------------------->
<nav class="mobile-navbar">
<div class="mobile-brand-title">Fox Bank</div>
<i class="fa-solid fa-bars"></i>
<div class="mobile-navbar-links">
<ul>
<li><a href="#">About</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Login</a></li>
</ul>
</div>
</nav>
<div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
</div>
</body>
</html>
导航栏变量包含节点列表,而不是导航栏元素,因此没有 classList
属性。
尝试更换
const mobileNavbar = document.getElementsByClassName("mobile-navbar");
const desktopNavbar = document.getElementsByClassName("desktop-navbar");
和
const mobileNavbar = document.querySelector(".mobile-navbar");
const desktopNavbar = document.querySelector(".desktop-navbar");
或将 [0]
添加到节点列表值之后 select 每个列表中的第一个元素。
所以我试图让我的导航栏在人们滚动时保持在页面顶部,但它不想工作。出于某种原因,控制台不断抛出错误,指出 classList.remove()
属性未定义。但与此同时,当我移除它们时,导航栏不会粘住。
如果有帮助,我构建了两个导航栏。一个用于 mobile/tablet,另一个用于台式机。
这是怎么回事?
// ---------------------------------------- GLOBAL VARIABLES
const mobileNavbar = document.getElementsByClassName("mobile-navbar");
const desktopNavbar = document.getElementsByClassName("desktop-navbar");
const stickyDesktop = desktopNavbar.offsetTop;
const stickyMobile = mobileNavbar.offsetTop;
window.onscroll = function () {
stickyNav()
};
function stickyNav() {
if (window.pageYOffset >= stickyDesktop || window.pageYOffset >= stickyMobile) {
desktopNavbar.classList.add("sticky");
mobileNavbar.classList.add("sticky");
}
else {
desktopNavbar.classList.remove("sticky");
mobileNavbar.classList.remove("sticky");
}
}
// ---------------------------------------- DESKTOP NAVBAR
document.addEventListener('click', e => {
const isDropdownButton = e.target.matches("[data-dropdown-button]")
if (!isDropdownButton && e.target.closest('[data-dropdown]') != null) return
let currentDropdown
if (isDropdownButton) {
currentDropdown = e.target.closest('[data-dropdown]')
currentDropdown.classList.toggle('active')
}
document.querySelectorAll('[data-dropdown].active').forEach(dropdown => {
if (dropdown === currentDropdown) return
dropdown.classList.remove('active')
})
})
// ---------------------------------------- MOBILE NAVBAR
const toggleButton = document.getElementsByClassName('fa-bars')[0]
const mobileNavBar = document.getElementsByClassName('mobile-navbar-links')[0]
toggleButton.addEventListener('click', () => {
mobileNavBar.classList.toggle('active')
})
* {
box-sizing: border-box;
}
a {
text-decoration: none;
color: #000;
}
body {
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
}
.sticky {
position: fixed;
top: 0;
width: 100%;
}
.sticky + body {
padding-top: 60px;
}
.scrollDown {
position: absolute;
top: 93%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.scrollDown a {
text-decoration: none;
}
.scrollDown p {
margin: 0;
font-family: 'Nunito', sans-serif;
font-size: 20px;
color: #fff;
}
.fa-chevron-down,
.fa-chevron-up {
width: 50px;
height: 50px;
font-size: 32px;
color: #fff;
;
}
.scrollDown:hover {
transition: .2s ease;
}
@media screen and (max-width: 600px) {
/* ------------------------------- MOBILE NAVBAR */
.desktop-navbar {
display: none;
}
.mobile-navbar {
display: flex;
overflow: hidden;
justify-content: space-between;
align-items: center;
background-color: #333;
color: #fff;
}
.mobile-brand-title {
font-size: 1.5rem;
margin: .5rem;
}
.mobile-navbar-links ul {
margin: 0;
padding: 0;
display: flex;
}
.mobile-navbar-links li {
list-style: none;
}
.mobile-navbar-links li a {
color: #fff;
padding: 1rem;
display: block;
}
.mobile-navbar-links li:hover {
background-color: #555;
}
.mobile-navbar .fa-bars {
position: absolute;
display: none;
flex-direction: column;
justify-content: space-between;
top: .75rem;
right: 1rem;
color: #fff;
width: 1rem;
height: 1rem;
cursor: pointer;
}
.mobile-navbar .fa-bars {
display: flex;
}
.mobile-navbar-links {
display: none;
width: 100%;
}
.mobile-navbar {
flex-direction: column;
align-items: flex-start;
}
.mobile-navbar-links ul {
width: 100%;
flex-direction: column;
}
.mobile-navbar-links li {
text-align: center;
}
.mobile-navbar-links.active {
display: flex;
}
}
@media screen and (min-width: 601px) {
/* ------------------------------- DESKTOP NAVBAR */
.mobile-navbar {
display: none;
}
.desktop-navbar {
background-color: #f3f3f3;
overflow: hidden;
display: flex;
align-items: baseline;
padding: .5rem;
gap: 1rem;
}
.link {
background: none;
border: none;
text-decoration: none;
color: #777;
font-family: inherit;
font-size: inherit;
cursor: pointer;
padding: 0;
}
.dropdown.active+.link,
.link:hover {
color: #000;
}
.dropdown {
position: relative;
}
.dropdown-menu {
position: absolute;
left: 0;
top: calc(100% + .25rem);
background-color: #fff;
padding: .75rem;
border-radius: .25rem;
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.3);
z-index: 1000;
opacity: 0;
pointer-events: none;
transition: opacity 150ms ease, transform 150ms ease;
transform: translateY(-10px);
}
.dropdown.active>.link+.dropdown-menu {
opacity: 1;
transform: translateY(0px);
pointer-events: auto;
}
.information-grid {
display: grid;
grid-template-columns: repeat(2, max-content);
gap: 2rem;
}
.dropdown-links {
display: flex;
flex-direction: column;
gap: .25rem;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Fox Bank</title>
<!-- Meta tags -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Links/Styles -->
<link rel="stylesheet" href="styles/styles.css">
<link rel="stylesheet" href="styles/normalize.css">
<link rel="stylesheet" href="styles/responsive.css">
<link rel="stylesheet" href="styles/flickity.min.css" media="screen">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
<!-- Javascript -->
<script src="https://kit.fontawesome.com/8821130486.js" crossorigin="anonymous"></script>
<script src="js/jquery.js" defer></script>
<script src="js/app.js" async defer></script>
<script src="js/flickity.min.js" defer></script>
</head>
<body>
<!--------------------- DESKTOP NAVBAR -->
<!--------------------------------------->
<div class="desktop-navbar">
<div>
<a href="#">
<h1>Big Bank</h1>
</a>
</div>
<div class="dropdown" data-dropdown>
<button class="link" data-dropdown-button>About</button>
<div class="dropdown-menu information-grid">
<div>
<div class="dropdown-heading">Meet Our Team</div>
<div class="dropdown-links">
<a href="#" class="link">Staff</a>
<a href="#" class="link">Board of Directors</a>
</div>
</div>
<div>
<div class="dropdown-heading">Our History</div>
<div class="dropdown-links">
<a href="#" class="link">Overview</a>
<a href="#" class="link">Future</a>
</div>
</div>
<div>
<div class="dropdown-heading">Blog</div>
<div class="dropdown-links">
<a href="#" class="link">Latest Posts</a>
<a href="#" class="link">In The Community</a>
<a href="#" class="link">Security & Fraud Prevention</a>
<a href="#" class="link">National & International Money</a>
</div>
</div>
<div>
<div class="dropdown-heading">Contact Us</div>
<div class="dropdown-links">
<a href="#" class="link">Support Center</a>
<a href="#" class="link">Phone & Mailing Information</a>
<a href="#" class="link">Social Media</a>
</div>
</div>
</div>
</div>
<div class="dropdown" data-dropdown>
<button class="link" data-dropdown-button>Products</button>
<div class="dropdown-menu information-grid">
<div>
<div class="dropdown-heading">Checking</div>
<div class="dropdown-links">
<a href="#" class="link">Basic Checking</a>
<a href="#" class="link">Teens Checking</a>
<a href="#" class="link">Prime Checking</a>
<a href="#" class="link">Elite Checking</a>
</div>
</div>
<div>
<div class="dropdown-heading">Savings</div>
<div class="dropdown-links">
<a href="#" class="link">Basic Savings</a>
<a href="#" class="link">Teens Savings</a>
<a href="#" class="link">Prime Savings</a>
<a href="#" class="link">Elite Savings</a>
</div>
</div>
<div>
<div class="dropdown-heading">Borrow</div>
<div class="dropdown-links">
<a href="#" class="link">Personal Loans</a>
<a href="#" class="link">Auto Loans</a>
<a href="#" class="link">Credit Cards</a>
<a href="#" class="link">Mortgage</a>
<a href="#" class="link">Shark Loans</a>
</div>
</div>
<div>
<div class="dropdown-heading">Retirement</div>
<div class="dropdown-links">
<a href="#" class="link">Traditional IRA</a>
<a href="#" class="link">Roth IRA</a>
<a href="#" class="link">Self Employment IRA</a>
</div>
</div>
</div>
</div>
<a href="#"><button>Login</button></a>
</div>
<!---------------------- MOBILE NAVBAR -->
<!--------------------------------------->
<nav class="mobile-navbar">
<div class="mobile-brand-title">Fox Bank</div>
<i class="fa-solid fa-bars"></i>
<div class="mobile-navbar-links">
<ul>
<li><a href="#">About</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Login</a></li>
</ul>
</div>
</nav>
<div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
</div>
</body>
</html>
导航栏变量包含节点列表,而不是导航栏元素,因此没有 classList
属性。
尝试更换
const mobileNavbar = document.getElementsByClassName("mobile-navbar");
const desktopNavbar = document.getElementsByClassName("desktop-navbar");
和
const mobileNavbar = document.querySelector(".mobile-navbar");
const desktopNavbar = document.querySelector(".desktop-navbar");
或将 [0]
添加到节点列表值之后 select 每个列表中的第一个元素。