js
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
dropDown.forEach(element => {
element.addEventListener('click',()=>{
{
navItems.forEach(nav =>{
nav.classList.toggle('drop')
})
}
})
})
HTML
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
</ul>
CSS
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
display: none;
}
.drop{
display: block;
}
我有一个导航栏,每个导航栏项目都有下拉项目。我想在单击"下拉"类时显示这些下拉项。但问题是,当我点击其中一个时,所有的下拉列表都是可见的。如何仅显示我单击的列表?
输入以下代码
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
</style>
</head>
<body>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Click</button>
<div id="myDropdown" class="dropdown-content">
<a href="#home">Clicked</a>
<a href="#about">Clicked</a>
<a href="#contact">Clicked</a>
</div>
</div>
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
</body>
</html>
如注释中所述,最好使用事件委派技术。
算法很简单:
- 在父元素上添加侦听器
- 点击时检查是否点击了下拉式开启器
- 获取我需要打开的下拉列表
- 关闭其他下拉列表
- 从3打开下拉列表
const allDropdowns = document.querySelectorAll('.navbar__items')
const DROP_CLASS = 'drop';
const navbar = document.querySelector('.navbar');
navbar.addEventListener('click', ({target}) => {
if (!target.classList.contains('dropdown')) return;
const parent = target.parentNode;
const navItems = parent
.querySelector('.navbar__items');
allDropdowns.forEach(el => el !== navItems && el.classList.remove(DROP_CLASS));
if (navItems) {
navItems.classList.toggle(DROP_CLASS);
}
});
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
left: 80px;
display: none;
}
.drop{
display: block;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
</ul>
使用事件目标获取parentNode,然后使用parentNode查询隐藏元素,因为所有元素都分组在同一父/子分组中。此外,您还可以在每个元素中为隐藏的display: none;
设置一个初始类,并在单击时添加它。forEach循环在单击时使用隐藏类将每个元素设置为不显示。
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
// callback function that passes in the event => e from your listener
function showDropdown (e){
// set each navbar__items element display: none using hidden class
navItems.forEach(el => el.classList.add('hidden'))
// query the specific .navbar__items in the event.targets group
let dd = e.target.parentNode.querySelector('.navbar__items')
// remove the hidden class a nd show the dropdown for this event.target
dd.classList.remove('hidden')
}
// iterate over the dropdown element
dropDown.forEach(element => {
// function showDropdown on click
element.addEventListener('click', showDropdown)
})
.navbar {
position: relative;
}
.navbar__items {
position: absolute;
left: 75px;
}
.hidden {
display: none;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li><a href="#">clicked 1</a></li>
<li><a href="#">clicked 1</a></li>
<li><a href="#">clicked 1</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li><a href="#">clicked 2</a></li>
<li><a href="#">clicked 2</a></li>
<li><a href="#">clicked 2</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li><a href="#">clicked 3</a></li>
<li><a href="#">clicked 3</a></li>
<li><a href="#">clicked 3</a></li>
</ul>
</li>
</ul>
与其使用addEventlistener,不如将html中的onclick方法添加到具有相同方法名称的每个下拉列表中,但为每个下拉列表更改ul类名,然后在方法中传递类名,然后用参数类名切换下拉列表。
例如,
function onClick(item) {
if (document.getElementsByClassName(item).classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.remove('hidden');
}
if (!document.getElementsByClassName(item)[0].classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.add('hidden');
}
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items1')">click</div>
<ul class="navbar__items1 hidden">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items2')">click</div>
<ul class="navbar__items2 hidden">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items3')">click</div>
<ul class="navbar__items3 hidden">
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
<li><a href="#">clicked</a></li>
</ul>
</li>
</ul>