pyuntae
pyuntae

Reputation: 832

Second dropdown button in navigation bar showing the same content as the previous button?

My first dropdown button "Content" works correctly but when I click on the second dropdown button "Dropdown", the contents from the first dropdown button show up instead???

I have no idea why it is doing this??? Maybe I am overlooking a small detail, but I can't seem to find where I am going wrong with this.

/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */
function myFunction() {
  document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
  if (!e.target.matches('.dropbtn')) {
    var myDropdown = document.getElementById("myDropdown");
    if (myDropdown.classList.contains('show')) {
      myDropdown.classList.remove('show');
    }
  }
}
body {
  font-family: Raleway;
  font-size: 13px;
  margin: 0;
  padding: 0;
  height: 100%;
}

a {
  text-decoration: none;
  color: rosybrown
}

#titleNav {
  z-index: 2;
  /* added for fixed layout: keeps titleNav on top of other elemements */
  position: fixed;
  /* added for fixed layout */
  top: 0px;
  /* added for fixed layout */
  left: 0px;
  /* added for fixed layout */
  width: 100%;
  /* added for fixed layout */
  background-color: white;
  height: 60px;
  min-width: 600px;
  /* prevents nav links from wrapping when browser window is too narrow */
}

#title {
  float: left;
  padding-left: 2%;
  padding-top: 1.5%;
}

.navbar {
  overflow: hidden;
  float: right;
}

.navbar a {
  float: left;
  font-size: 16px;
  color: black;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
}

.dropdown {
  float: left;
  overflow: hidden;
}

.dropdown .dropbtn {
  cursor: pointer;
  font-size: 16px;
  border: none;
  outline: none;
  color: black;
  padding: 14px 16px;
  background-color: inherit;
  font-family: inherit;
  margin: 0;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  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;
}

.dropdown-content a:hover {
  background-color: #ddd;
}

.show {
  display: block;
}

.container {
  width: 100%;
}

#content {
  padding-top: 22%;
  padding-left: 15%;
  padding-right: 15%;
  text-align: justify;
  letter-spacing: 1px;
  line-height: 150%;
  padding-bottom: 60px;
}

.image {
  width: 100%;
  max-height: 500px;
  object-fit: fill;
}

.image:hover {
  opacity: 0.8;
  filter: alpha(opacity=50);
  /* For IE8 and earlier */
}

#footer {
  background-color: rgba(33, 33, 33, 0.89);
  position: fixed;
  bottom: 0px;
  left: 0xp;
  width: 100%;
  color: white;
  clear: both;
  text-align: center;
  padding: 5px;
}

.stopFloat {
  clear: both;
  left: 0px;
  right: 0px;
  bottom: 0px;
}
<html>

<head>
  <title>JS Framework</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  <link href="style.css" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>

<body>
  <div id="titleNav">
    <div id="title">
      <img src="pics/logo.png" width="160" height="39" alt="">
    </div>

    <div class="navbar">
      <a href="#home">Home</a>
      <div class="dropdown">
        <button class="dropbtn" onclick="myFunction()">Content
                        <i class="fa fa-caret-down"></i>
                    </button>
        <div class="dropdown-content" id="myDropdown">
          <a onclick="makeFramework('contentId', 'aboutUs.html');">About Us</a>
          <a onclick="makeFramework('contentId', 'aboutCoffee.html');">Coffee</a>
        </div>
      </div>
      <a href="#news">News</a>
      <div class="dropdown">
        <button class="dropbtn" onclick="myFunction()">Dropdown
                        <i class="fa fa-caret-down"></i>
                    </button>
        <div class="dropdown-content" id="myDropdown">
          <a href="#">Link 1</a>
          <a href="#">Link 2</a>
          <a href="#">Link 3</a>
        </div>
      </div>
      <a href="../labs.html">Labs</a>
    </div>
  </div>
  <div id="contentId">
    Content Area
  </div>

  <div id="footer">
    Web footer
  </div>

  <script src="framework.js"></script>
  <script src="dropDownMenu.js"></script>
  <script>
    "use strict";

    makeFramework('contentId', 'aboutUs.html');
  </script>
</body>

</html>

Upvotes: 0

Views: 318

Answers (1)

toastrackengima
toastrackengima

Reputation: 8742

Ummm.... because you call the same function from both buttons.

Essentially, you run the same piece of code, myFunction, despite which navigation item is clicked. Therefore, of course both items will always do the same thing.

Give each menu a different ID (remember that IDs need to be unique - i.e. you can't have two items with the same ID), and make myFunction take the ID of the element to show / hide, as shown below.

This means that there is a way for the function to determine which menu open, and thus it will open the correct one.

/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */
function myFunction(id) {
  document.getElementById(id).classList.toggle("show");
}

// Close the dropdown if the user clicks outside of it
window.onmouseup = function(e) {
  var dropdown = document.querySelector(".dropdown-content.show"); //Get any shown dropdown element (i.e. any element on the page with both the dropdown-content class and the show class
  if (dropdown) { //If such an element exists, a dropdown needs to be closed
    dropdown.classList.remove("show"); //So remove the show class
  }
}
body {
  font-family: Raleway;
  font-size: 13px;
  margin: 0;
  padding: 0;
  height: 100%;
}

a {
  text-decoration: none;
  color: rosybrown
}

#titleNav {
  z-index: 2;
  /* added for fixed layout: keeps titleNav on top of other elemements */
  position: fixed;
  /* added for fixed layout */
  top: 0px;
  /* added for fixed layout */
  left: 0px;
  /* added for fixed layout */
  width: 100%;
  /* added for fixed layout */
  background-color: white;
  height: 60px;
  min-width: 600px;
  /* prevents nav links from wrapping when browser window is too narrow */
}

#title {
  float: left;
  padding-left: 2%;
  padding-top: 1.5%;
}

.navbar {
  overflow: hidden;
  float: right;
}

.navbar a {
  float: left;
  font-size: 16px;
  color: black;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
}

.dropdown {
  float: left;
  overflow: hidden;
}

.dropdown .dropbtn {
  cursor: pointer;
  font-size: 16px;
  border: none;
  outline: none;
  color: black;
  padding: 14px 16px;
  background-color: inherit;
  font-family: inherit;
  margin: 0;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  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;
}

.dropdown-content a:hover {
  background-color: #ddd;
}

.show {
  display: block;
}

.container {
  width: 100%;
}

#content {
  padding-top: 22%;
  padding-left: 15%;
  padding-right: 15%;
  text-align: justify;
  letter-spacing: 1px;
  line-height: 150%;
  padding-bottom: 60px;
}

.image {
  width: 100%;
  max-height: 500px;
  object-fit: fill;
}

.image:hover {
  opacity: 0.8;
  filter: alpha(opacity=50);
  /* For IE8 and earlier */
}

#footer {
  background-color: rgba(33, 33, 33, 0.89);
  position: fixed;
  bottom: 0px;
  left: 0xp;
  width: 100%;
  color: white;
  clear: both;
  text-align: center;
  padding: 5px;
}

.stopFloat {
  clear: both;
  left: 0px;
  right: 0px;
  bottom: 0px;
}
<html>

<head>
  <title>JS Framework</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  <link href="style.css" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>

<body>
  <div id="titleNav">
    <div id="title">
      <img src="pics/logo.png" width="160" height="39" alt="">
    </div>

    <div class="navbar">
      <a href="#home">Home</a>
      <div class="dropdown">
        <button class="dropbtn" onclick="myFunction('dropdownOne')">Content
                        <i class="fa fa-caret-down"></i>
                    </button>
        <div class="dropdown-content" id="dropdownOne">
          <a onclick="makeFramework('contentId', 'aboutUs.html');">About Us</a>
          <a onclick="makeFramework('contentId', 'aboutCoffee.html');">Coffee</a>
        </div>
      </div>
      <a href="#news">News</a>
      <div class="dropdown">
        <button class="dropbtn" onclick="myFunction('dropdownTwo')">Dropdown
                        <i class="fa fa-caret-down"></i>
                    </button>
        <div class="dropdown-content" id="dropdownTwo">
          <a href="#">Link 1</a>
          <a href="#">Link 2</a>
          <a href="#">Link 3</a>
        </div>
      </div>
      <a href="../labs.html">Labs</a>
    </div>
  </div>
  <div id="contentId">
    Content Area
  </div>

  <div id="footer">
    Web footer
  </div>

  <script src="framework.js"></script>
  <script src="dropDownMenu.js"></script>
  <script>
    "use strict";

    makeFramework('contentId', 'aboutUs.html');
  </script>
</body>

</html>

How does this work?

myFunction('dropdownOne') means that the id variable in myFunction is given the value dropdownOne - therefore when we call document.getElementById(id) it will interpret as document.getElementById('dropdownOne') instead, and hence the first dropdown is targeted.

Likewise, if we call myFunction('dropdownTwo'), then it will interpret as document.getElementById('dropdownTwo'), and thus target the second dropdown.

Therefore, you can add as many menu items like this as you want, assuming each has a unique identifier, and myFunction is given the unique ID each time.

Upvotes: 2

Related Questions