所以我正在尝试为移动设备创建多级导航,但我遇到了一些问题。我还在学习javascript,所以请和我一起裸露。这是代码笔的链接:
https://codepen.io/maciekmat/pen/yLepYKq
因此,当您按下右上角的菜单时,将打开一个菜单。然后我希望能够进入子类别。例如,单击"测试打开",将分配 .active 类,并滑入另一个菜单。现在我想有一个返回按钮,它基本上删除了 .active 类。
然而,我认为正在发生的事情,事件侦听器侦听整个父级,并且在子导航内单击的任何地方,它都会将其注册为单击,并运行 .active 类。当我单击返回时,它就像 .active 被删除并立即应用回来。请帮忙吗?
我尝试做event.currentEvent !== event.target if 语句,但没有运气
const nav = document.getElementById('menuIcon')
const dropdown = document.getElementById('menuDropdown')
nav.addEventListener('click', function() {
dropdown.classList.toggle('nav-is-toggled')
});
const grabNavLinks = document.querySelectorAll('.sub-nav-link');
const grabBackLinks = document.querySelectorAll('.nav-link.back');
const subNavLinks = Array.from(grabNavLinks);
const backLinks = Array.from(grabBackLinks);
for (let i = 0; i < subNavLinks.length; i++) {
subNavLinks[i].addEventListener("click", function() {
this.querySelector('.sub-nav').classList.add('active');
});
}
for (let i = 0; i < backLinks.length; i++) {
backLinks[i].addEventListener("click", function() {
document.querySelector('.sub-nav').classList.remove('active');
});
}
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap");
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: "Open sans", sans-serif;
background: #F9F9F9;
box-sizing: border-box;
}
a, p, h1, h2, h3 {
margin: 0;
padding: 0;
text-decoration: none;
}
ul, li {
padding: 0;
margin: 0;
}
header {
background: white;
padding: 24px 30px;
display: flex;
flex-direction: column;
z-index: 10;
position: relative;
}
.top-nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.top-nav .logo {
background: url("images/tcb-logo-brand.svg") no-repeat;
width: 150px;
height: 50px;
background-size: contain;
background-position: center;
}
.top-nav .navigation {
display: flex;
justify-content: space-between;
width: 132px;
height: 26px;
}
.top-nav .navigation .nav-item {
width: 23px;
height: 26px;
margin-left: 10px;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.top-nav .navigation .nav-item.menu {
background-image: url("images/menu-icon.svg");
}
.top-nav .navigation .nav-item.notification {
background-image: url("images/bell-icon.svg");
}
.top-nav .navigation .nav-item.my-account {
background-image: url("images/acc-icon.svg");
}
.search {
margin-top: 16px;
}
.search input[type=search] {
outline: none;
border: none;
background: #F6F6F6;
width: 100%;
height: 50px;
font-size: 16px;
padding: 10px 0 10px 20px;
background-image: url("images/search-icon.svg");
background-repeat: no-repeat;
background-position: right 15px top 50%;
}
.search input[type=search]::placeholder {
color: #B7B7B7;
}
span.nav-title {
display: none;
}
nav.main-nav {
width: 100%;
background: #F6F6F6;
transform: translateY(-100%);
z-index: 0;
position: relative;
transition: all 0.3s ease-in-out;
position: absolute;
padding-bottom: 50px;
overflow: hidden;
}
nav.main-nav ul {
padding-top: 2px;
position: relative;
}
nav.main-nav li {
list-style: none;
}
nav.main-nav a {
color: #6D6D6D;
font-size: 16px;
width: 100%;
height: 100%;
display: block;
padding: 18px 30px;
border-bottom: 1px solid #E9E9E9;
}
nav.main-nav li.nav-link.arrow {
background: url("images/right-arrow.svg") no-repeat;
background-position: right 30px top 50%;
}
nav.main-nav ul.sub-nav {
background: #cecece;
width: 100%;
display: flex;
flex-direction: column;
transform: translateX(100%);
overflow: hidden;
visibility: hidden;
opacity: 0;
position: absolute;
top: 0;
left: 0;
transition: transform 0.2s ease;
}
.sub-nav-link > .sub-nav.active {
transform: translateX(0);
visibility: visible;
opacity: 1;
}
nav.nav-is-toggled {
position: static;
opacity: 1;
transform: translateY(0);
transition: all 0.3s ease-in-out;
}
<header>
<div class="top-nav">
<div class="logo"></div>
<div class="navigation">
<div id="menuIcon" class="nav-item menu">test</div>
<div class="nav-item notification"></div>
<div class="nav-item my-account"><span class="nav-title">My Account</span></div>
</div>
</div>
<div class="search">
<input type="search" name="search" id="search" placeholder="Search by store...">
</div>
</header>
<nav id="menuDropdown" class="main-nav">
<ul class="main-nav-ul">
<li class="nav-link"><a href="#">Test</a></li>
<li class="nav-link arrow sub-nav-link"><a href="#">Test Open</a>
<ul class="sub-nav">
<li class="nav-link back"><a href="#">Go Back</a></li>
<li class="nav-link"><a href="#">Test</a></li>
<li class="nav-link"><a href="#">Test</a></li>
<li class="nav-link"><a href="#">Test</a></li>
</ul>
</li>
<li class="nav-link"><a href="#">Test</a></li>
<li class="nav-link"><a href="#">Test</a></li>
<li class="nav-link arrow sub-nav-link"><a href="#">Test Open</a>
<ul class="sub-nav">
<li class="nav-link back"><a href="#">Go Back</a></li>
<li class="nav-link"><a href="#">Test</a></li>
<li class="nav-link"><a href="#">Test</a></li>
</ul>
</li>
<li class="nav-link"><a href="#">Test</a></li>
</ul>
</nav>
<script src="navigation.js"></script>
去阅读事件冒泡以及它如何在 DOM 树中冒泡。但是,由于它从父级传递到子级的方式(也就是说,它在树上冒泡(,您应该调用event.stopPropagation();
,以便上一个事件不会冒泡到backLinks
事件侦听器中。
这是你应该做的
for (let i = 0; i < backLinks.length; i++) {
backLinks[i].addEventListener("click", function(event) {
event.stopPropagation();
document.querySelector('.sub-nav').classList.remove('active');
});
}