提问人:Born2DoubleUp 提问时间:10/5/2017 更新时间:8/3/2020 访问量:8387
如何在打开一个 Javascript 下拉菜单时关闭另一个下拉菜单
How to Close One Javascript Drop Down Menu When Opening Another
问:
我不熟悉 JavaScript,我希望能得到一些帮助来解决我似乎无法解决的问题。我目前在我的网站上有 2 个下拉菜单。一个是导航的下拉菜单,在单击汉堡菜单图标时激活。第二个下拉列表用于在我的网站上显示类别。目前,当我单击一个下拉列表时,我必须再次单击它才能关闭它。如果我单击第二个下拉列表而不关闭第一个下拉列表,则两者都将保持可见。我想发生的是两件事。首先,我希望它,如果用户单击下拉菜单 div 之外的任何地方,它会自动关闭。我希望看到的第二件事是一次只能看到一个下拉菜单。因此,如果我单击一个并且另一个下拉列表打开,我希望它关闭。希望我能很好地解释这一点。现在谈谈我正在使用的代码。
以下是我的脑海中。
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function DropDownMenuNavigation() {
document.getElementById("b2DropDownMenuNav").classList.toggle("show");
}
function DropDownMenuCategory() {
document.getElementById("b2DropDownMenuCat").classList.toggle("show");
}
</script>
然后我用它作为按钮来激活导航下拉菜单。这包含在我的身体里。
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuNavigation()" class="dropbtn">☰ MENU</button>
</div>
这是我用来包含我的类别下拉菜单的。
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCategory()" class="dropbtn">CATEGORIES</button>
</div>
最后是我使用的css,只是有机会帮助任何人。
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block;}
那么,按照我的要求去做最好的方法是什么呢?有人可以帮我一把,为我指明正确的方向。非常感谢,感谢您能给我的任何帮助。
答:
该属性不应包含 .它应该看起来像这样:onclick
()
<button onclick="DropDownMenuNavigation" class="dropbtn">☰ MENU</button>
或者,更好的是,不要将事件侦听器内联,而是将其放在脚本中。
此外,在按下按钮时从另一个下拉列表中删除“show”类。
请看这里:
document.getElementById('menudropbtn').addEventListener('click', function () {
document.getElementById('b2DropDownMenuNav').classList.toggle('show')
document.getElementById('b2DropDownMenuCat').classList.remove('show')
})
document.getElementById('categoriesdropbtn').addEventListener('click', function () {
document.getElementById('b2DropDownMenuCat').classList.toggle('show')
document.getElementById('b2DropDownMenuNav').classList.remove('show')
})
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
display: block;
}
<div class="dropbtn" style="float: left;">
<button class="dropbtn" id="menudropbtn">☰ MENU</button>
<div class="dropdown">
<div class="dropdown-content" id="b2DropDownMenuNav">
<a>Something</a>
</div>
</div>
</div>
<div class="dropbtn" style="float: left;">
<button class="dropbtn" id="categoriesdropbtn">CATEGORIES</button>
<div class="dropdown">
<div class="dropdown-content" id="b2DropDownMenuCat">
<a>Something else</a>
</div>
</div>
</div>
评论
也许以下代码可以提供帮助。您可以使用自定义事件让模块项(如菜单、弹出窗口等)相互通信。
如果单击菜单按钮,则可以调度自定义事件。页面上的任何其他项目都可以根据此事件执行某些操作(例如在打开主菜单时暂停游戏)。
// find menu-content in item (=menu-button) and return
// "none" if menu-content.style.display is "block"
// "block" if menu-content.style.display is not "block"
const toggle =
(item) => {
const content =
item.querySelector("[x-role=\"menu-content\"]");
return content.style.display === "block"
? "none"
: "block"
}
;
// set menu-content found in item (=menu-button) to
// none or block
const changeDisplay =
(item,display) =>
item.querySelector("[x-role=\"menu-content\"]")
.style.display = display;
// when menu-button is clicked
const menuButtonClicked =
e => {
//get the toggled content style
// if current style is block then
// toggled is none and vice versa
const style = toggle(e.target);
//hide all menus, in the for each we
// added an event listener for "menu-click" event
// the listener will hide the menu
var evt = new Event("menu-click",{});
document.body.dispatchEvent(evt);
//set style of the current
changeDisplay(e.target,style);
}
;
//for each menu-botton role
// I am not using css selectors on class, class is for style,
// user defined properties can be used for behavior.
// If you mix this up then you can break style, behavior
// or both when changing behavior or style
document.querySelectorAll("[x-role=\"menu-button\"]")
.forEach(
x => {
//when clicked let menuButtonClicked handle it
x.addEventListener(
"click"
,menuButtonClicked
);
//listen to custom event called "menu-click"
// set display to none when this happens
// if you were to dynamically add and remove
// menu items then you should remove the event
// listeners when you remove the menu
document.body.addEventListener(
"menu-click"
,e => changeDisplay(x,"none")
);
}
)
;
.menu-button {
cursor: pointer;
}
.menu-content {
display:none;
}
<div class="menu-button" x-role="menu-button">
menu1
<div class="menu-content" x-role="menu-content">
<ul>
<li>one</li>
<li>two</li>
</ul>
</div>
</div>
<div class="menu-button" x-role="menu-button">
menu2
<div class="menu-content" x-role="menu-content">
<ul>
<li>three</li>
<li>four</li>
</ul>
</div>
</div>
<div class="menu-button" x-role="menu-button">
menu3
<div class="menu-content" x-role="menu-content">
<ul>
<li>five</li>
<li>six</li>
</ul>
</div>
</div>
为此,您可以添加自定义 JS 函数,这些函数将根据元素 ID 打开下拉列表,当打开一个下拉列表时,所有其他下拉列表都将关闭。您可以创建一个关闭所有下拉列表的函数。然后,在“打开”函数中,首先调用“close_all”函数。
这是一个工作片段。
// Functions for Interactive File Menu Bar
// - Click Butoon to Open Dropdown
// - Clicking one dropdown closes all other
// - Clicking outside the file menu bar will close all the dropdown.
function open_dropdown(element_id) {
console.log('Opening Dropdown:', element_id)
close_all_dropdowns()
document.getElementById(element_id).style.display = 'block';
}
// Close the dropdown if the user clicks outside of it
function close_dropdown(element) {
console.log('I am closing dropdown:', element)
element.style.display = 'none'
}
// Close all dropdowns.
function close_all_dropdowns() {
var dropdowns = document.getElementsByClassName('dropdown-content')
for (var i = 0; i < dropdowns.length; i++) {
close_dropdown(dropdowns[i]);
}
}
// Close all dropdowns when clicking outside.
window.onclick = function (e) {
if (!e.target.matches('.dropbtn')) {
close_all_dropdowns()
}
}
/* Styles for the File Menu Bar. */
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/98.css">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<title>RetroNet</title>
</head>
<body>
<div class="window" style="width: 100%">
<div class="title-bar">
<div class="title-bar-text">Welcome to RetroNet!</div>
<div class="title-bar-controls">
<button aria-label="Minimize"></button>
<button aria-label="Maximize"></button>
<button aria-label="Close"></button>
</div>
</div>
<!-- Main menu -->
<div class="window-body">
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_file')">File</button>
<div class="dropdown-content" id="dd_file">
<a href="#">Open</a>
<a href="#">Close</a>
<a href="#">Settings</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_edit')">Edit</button>
<div class="dropdown-content" id="dd_edit">
<a href="#">Cut</a>
<a href="#">Copy</a>
<a href="#">Paste</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_view')">View</button>
<div class="dropdown-content" id="dd_view">
<a href="#">Toggle CSS</a>
<a href="#">Toggle Javascript</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_tools')">Tools</button>
<div class="dropdown-content" id="dd_tools">
<a href="#">Not Decided</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_favorite')">Favourties</button>
<div class="dropdown-content" id="dd_favorite">
<a href="#">Add New Favorite</a>
<a href="#">Add this Page to Favorites</a>
<a href="#">Show Favorites</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_help')">Help</button>
<div class="dropdown-content" id="dd_help">
<a
href="https://github.com/ayushxx7/summer-code-jam-2020/blob/master/adventurous-anteaters/README.md">README</a>
</div>
</div>
</div>
</div>
</body>
</html>
评论
document.getElementById("b2DropDownMenuNav").classList.remove("show");