最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - How to Close One Javascript Drop Down Menu When Opening Another - Stack Overflow

programmeradmin1浏览0评论

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. I currently have 2 Drop Down Menus on my website. 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. 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.

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

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. I currently have 2 Drop Down Menus on my website. 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. 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.

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

Share Improve this question asked Oct 5, 2017 at 1:17 Born2DoubleUpBorn2DoubleUp 1091 silver badge12 bronze badges 4
  • so select the other one and remove the class – epascarello Commented Oct 5, 2017 at 1:20
  • Yeah, I thought of doing it but everything I experimented with didn't seem to work out for me. How would I go about doing this? All I would be doing is removing the class "show" from the opposite drop down menu? – Born2DoubleUp Commented Oct 5, 2017 at 1:24
  • So you did: document.getElementById("b2DropDownMenuNav").classList.remove("show"); – epascarello Commented Oct 5, 2017 at 1:30
  • Yeah, I tried that and it didn't have any effect from what I could see. I put it right after the toggle line and it didn't do anything. I placed it before the toggle line and nothing happens when I click either button. – Born2DoubleUp Commented Oct 5, 2017 at 1:32
Add a ment  | 

3 Answers 3

Reset to default 2

The onclick attribute shouldn’t include the (). 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.

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. You can create a function that closes all the dropdowns. Then, in your "open" function, call the "close_all" function first.

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./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">Wele 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./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) municate 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>

发布评论

评论列表(0)

  1. 暂无评论