简体   繁体   English

打开另一个时如何关闭一个 Javascript 下拉菜单

[英]How to Close One Javascript Drop Down Menu When Opening Another

I'm not to familiar with JavaScript and I was hoping to get a little help with a problem I can't seem to fix.我对 JavaScript 不太熟悉,我希望能得到一些我似乎无法解决的问题的帮助。 I currently have 2 Drop Down Menus on my website.我目前在我的网站上有 2 个下拉菜单。 One is a drop down menu for the navigation which is activated when clicking a hamburger menu icon.一个是导航的下拉菜单,单击汉堡菜单图标时会激活该菜单。 The second drop down is being used to show categories on my website.第二个下拉列表用于在我的网站上显示类别。 Currently when I click one drop down, I have to click it again in order to close it.目前,当我单击一个下拉菜单时,我必须再次单击它才能关闭它。 If I click the second drop down without closing the first both will remain visible.如果我单击第二个下拉菜单而不关闭第一个下拉菜单,两者都将保持可见。 What I would like to happen is two things.我希望发生的是两件事。 First I would like it so that if a user clicks anywhere outside of the div for the drop down menu it automatically closes.首先,我希望这样,如果用户单击 div 之外的任何地方以获取下拉菜单,它会自动关闭。 The second thing I would like to see happen is only have one drop down menu visible at a time.我希望看到的第二件事是一次只能看到一个下拉菜单。 So if I click one and another drop down is open I want it to be closed.因此,如果我单击一个下拉菜单并打开另一个下拉菜单,我希望将其关闭。 Hopefully I explained this well.希望我解释得很好。 Now onto the code I'm using.现在进入我正在使用的代码。

The following is within my head.以下在我的脑海中。

<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>

Then I use this as the button to activate the navigation drop down menu.然后我用它作为按钮来激活导航下拉菜单。 This is included within my body.这包括在我的身体里。

<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuNavigation()" class="dropbtn">&#9776; MENU</button>
</div>

and this what I use to include my category drop down menu.这就是我用来包含我的类别下拉菜单的内容。

<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCategory()" class="dropbtn">CATEGORIES</button>
</div>

Now lastly is the css I use just on the off chance that helps any.现在最后是我偶尔使用的 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;} 

So what would be the best method to go about doing what I'm asking?那么什么是最好的方法来做我要问的事情? Could someone maybe lend me a hand and point me in the right direction.有人可以帮我一把,并指出我正确的方向。 Thanks a lot and I appreciate any help you could lend me.非常感谢,我很感激你能借给我的任何帮助。

The onclick attribute shouldn't include the () . onclick属性不应包含() It should look like this:它应该是这样的:

<button onclick="DropDownMenuNavigation" class="dropbtn">&#9776; MENU</button>

Or—even better—don't put the event listener inline, put it in the script.或者——甚至更好——不要将事件侦听器内联,而是将它放在脚本中。

Also, remove the “show” class from the other dropdown when the button is pressed.此外,当按下按钮时,从另一个下拉列表中删除“show”类。

See here:看这里:

 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">&#9776; 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>

To do this, you can add custom JS functions that will open dropdowns based on element ID, and when one dropdown is opened, all others will be closed.为此,您可以添加自定义 JS 函数,该函数将根据元素 ID 打开下拉列表,并且当打开一个下拉列表时,所有其他下拉列表都将关闭。 You can create a function that closes all the dropdowns.您可以创建一个关闭所有下拉菜单的函数。 Then, in your "open" function, call the "close_all" function first.然后,在您的“打开”函数中,首先调用“close_all”函数。

Here's a working snippet.这是一个工作片段。

 // 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>

Maybe the following code can help.也许以下代码可以提供帮助。 You can use custom event to have module items (like menu, popup or such) communicate to each other.您可以使用自定义事件让模块项目(如菜单、弹出窗口等)相互通信。

If a menu button is clicked then you can dispatch a custom event.如果单击菜单按钮,则可以调度自定义事件。 Any other item on the page may do something according to what this event is (like pausing a game when a main menu is opened).页面上的任何其他项目可能会根据此事件的内容执行某些操作(例如在打开主菜单时暂停游戏)。

 // 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM