Buttons suddenly not working and dropdown list is not functioning after some styling

Viewed 46

Buttons suddenly not working and dropdown list is not functioning after some styling. When the dropdown was working it was opening to the top right side no matter which button you pressed. I tried a few things to fix it but I couldn't find an answer. I've stared at the code for a while and I really can't see what I did wrong. I'm assuming I've just been looking at it to long. At this point I'm considering restarting the button portion of the site so I hopefully don't make the same mistake twice. This is sized for an Iphone SE in the dev debugger tool. I'm sure one of you will spot the issue right away so any help would be greatly appreciated.

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="en">
        <title>Spellmann Laboratories</title>
        <link rel="stylesheet" href="style.css" type="text/css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
    </head>
    <body>
        <header>
            <h1>Spellmann Laboratories</h1>
                <nav>
                <ul class="navbar">
                    <li class="navitem"><a href="#">Home</a></li>
                    <li class="navitem"><a href="../Spellmann-Laboratories/about.html">About</a></li>
                    <li class="navitem"><a href="../Spellmann-Laboratories/Contact.html">Contact</a></li>
                </ul>
            </nav>
        </header>
        <div class="parent">
            <div class="parentcontainer">
                <button onclick="myfunction()" class="dropbtn">Cannabinoids</button>
                <i class="fa fa-angle-right" aria-hidden="true"></i>
                <div id="mydropdown" class="dropdown">
                    <a>Link1</a>
                    <a>Link2</a>
                    <a>Link3</a>
                </div>
            </div>
            <div class="parentcontainer">
                <button onclick="myfunction()" class="dropbtn">Cathinones</button>
                <i class="fa fa-angle-right" aria-hidden="true"></i>
                <div id="mydropdown" class="dropdown">
                    <a>Link1</a>
                    <a>Link2</a>
                    <a>Link3</a>
                </div>
            </div>
            <div class="parentcontainer">
                <button onclick="myfunction()" class="dropbtn">Dissociatives</button>
                <i class="fa fa-angle-right" aria-hidden="true"></i>
                <div id="mydropdown" class="dropdown">
                    <a>Link1</a>
                    <a>Link2</a>
                    <a>Link3</a>
                </div>
            </div>
            <div class="parentcontainer">
                <button onclick="myfunction()" class="dropbtn">Opioids</button>
                <i class="fa fa-angle-right" aria-hidden="true"></i>
                <div id="mydropdown" class="dropdown">
                    <a>Link1</a>
                    <a>Link2</a>
                    <a>Link3</a>
                </div>
            </div>
            <div class="parentcontainer">
                <button onclick="myfunction()" class="dropbtn">Phenethylamines</button>
                <i class="fa fa-angle-right" aria-hidden="true"></i>
                <div id="mydropdown" class="dropdown">
                    <a>Link1</a>
                    <a>Link2</a>
                    <a>Link3</a>
                </div>
            </div>
            <div class="parentcontainer">
                <button onclick="myfunction()" class="dropbtn">tryptamines</button>
                <i class="fa fa-angle-right" aria-hidden="true"></i>
                <div id="mydropdown" class="dropdown">
                    <a>Link1</a>
                    <a>Link2</a>
                    <a>Link3</a>
                </div>
            </div>
        </div>
        <div class="parentimg">
            <img class="placeholderimgcontent" src="../XSS4-Repository/Images/placeholderimg.jpeg">
        </div>
        <div class="insta">
            <a href="#">Follow us on Instagram!</a>
        </div>
        <script defer type="text/javascript" src="../Spellmann-Laboratories/main.js"></script>
    </body>
</html>

CSS:

body {
    font-family: Georgia, 'Times New Roman', Times, serif;
}

h1 {
    text-align: center;
    transform: translate(0,140px);
    font-size: 3.5em;
}

.navbar {
    background-color: #666;
    display: flex;
    list-style: none;
    justify-content: space-evenly;
    flex-wrap: wrap;
    padding-top: 50px;
    padding-bottom: 100px;
    margin: 25px 25px 0 25px;
}

.spellab {
    font-weight: bold;
    font-size: 3.5em;
    margin-top: 50px;
}

.navitem {
    margin-top: 60px;
    font-size: 2.25em;
    transform: translate(-22px,50px);
}

.navitem a {
    color: black;
    text-decoration: none;
    text-align: center;
}

.parent {
    background-color: #666;
    margin: 25px 150px 0 150px;
    padding: 15px 0 15px 0;
    font-size: 2em;
}

.parentcontainer {
    text-align: center;
    margin: auto;
}

button {
    border: none;
    background-color: #666;
    font-size: 1.25em;
}

.dropdown a {
    display: none;
}

.show {
    display: block;
}

.parentimg {
    display: flex;
    justify-content: center;
}

.placeholderimgcontent {
    height: auto;
    width: auto;
    margin: 25px 25px 0 25px;
}

.insta {
    text-align: center;
    margin: 25px 25px 0 25px;
}

.insta a {
    display: flex;
    justify-content: center;
    font-size: 3em;
    text-decoration: none;
    color: black;
    background-color: #666;
    padding-top: 50px;
    padding-bottom: 50px;
}

a:hover, a:focus {
    background-color: #999;
    cursor: pointer;
}

JS:

/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
document.querySelector('.dropbtn').addEventListener('click', function() {
    document.getElementById("mydropdown").classList.toggle("show");
  });
  
  // Close the dropdown menu if the user clicks outside of it
  window.onclick = function(event) {
    if (!event.target.matches('.dropbtn')) {
      var dropdowns = document.getElementsByClassName("dropdown");
      var i;
      for (i = 0; i < dropdowns.length; i++) {
        var openDropdown = dropdowns[i];
        if (openDropdown.classList.contains('show')) {
          openDropdown.classList.remove('show');
        }
      }
    }
  }
3 Answers

you are calling the function myFunction and you don't define it in Javascript. You should change this:

document.querySelector('.dropbtn').addEventListener('click', function() {
    document.getElementById("mydropdown").classList.toggle("show");
  });

to:

function myFunction() {
  document.getElementById("mydropdown").classList.toggle("show");
}

You should remove

.dropdown a {
    display: none;
}

and instead add something like this (this css is from w3schools):

.parentcontainer {
  position: relative;
  display: inline-block;
}

.dropdown {
  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 a {
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}

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

I believe it should work now! p.s. You should also change <button onclick="myfunction()"in your html to myFunction in all occurrences.

Sorry to hear that. I'll try to make it more clear by example. However this will only work for ONE menu. You can't reference two menus by the same id, id has to be unique. So you would need to select all the menus by querySelectorAll('.className'), which returns an array, but I will put that in the next answer so it's clearer. So this would work for one menu, but not for more than one:

HTML dropdown button:

<div class="parentcontainer">
  <button onclick="myfunction()" class="dropbtn">tryptamines</button>
  <i class="fa fa-angle-right" aria-hidden="true"></i>
  <div id="mydropdown" class="dropdown">
    <a href="#">Link1</a>
    <a href="#">Link2</a>
    <a href="#">Link3</a>
  </div>
</div>

CSS

.dropbtn {
  background-color: #3498db;
  color: white;
  padding: 16px;
  font-size: 16px;
  border: none;
  cursor: pointer;
}

.dropbtn:hover,
.dropbtn:focus {
  background-color: #2980b9;
}

.parentcontainer {
  position: relative;
  display: inline-block;
}

.dropdown {
  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 a {
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}

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

.show {
  display: block;
}

JS:

function myfunction() {
  document.getElementById("mydropdown").classList.toggle("show");
}

// Close the dropdown if the user clicks outside of it
window.onclick = function (event) {
  if (!event.target.matches(".dropbtn")) {
    var dropdowns = document.getElementsByClassName("dropdown");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains("show")) {
        openDropdown.classList.remove("show");
      }
    }
  }
};

So here's a solution for 2 or more menus. HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="style.css" />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css"
      integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
      crossorigin="anonymous"
    />
  </head>
  <body>
    <div class="d-flex justify-content-around">
      <div class="parentcontainer">
        <div class="dropbtn on-dropdown">Cannabinoids</div>
        <div class="dropdown">
          <ul>
            <li><a href="#">Link 1</a></li>
            <li><a href="#">Link 2</a></li>
            <li><a href="#">Link 3</a></li>
            <li><a href="#">Link 4</a></li>
          </ul>
        </div>
      </div>
      <div class="parentcontainer">
        <div class="dropbtn on-dropdown">Cathinones</div>
        <div class="dropdown">
          <ul>
            <li><a href="#">Link 1</a></li>
            <li><a href="#">Link 2</a></li>
            <li><a href="#">Link 3</a></li>
            <li><a href="#">Link 4</a></li>
          </ul>
        </div>
      </div>
    </div>

    <script src="script.js"></script>
  </body>
</html>

CSS

* {
  box-sizing: border-box;
}

.dropbtn {
  background-color: #3498db;
  color: white;
  padding: 18px 20px;
  font-size: 16px;
  border: none;
  cursor: pointer;
  position: relative;
  transition: all ease-in-out 0.3s;
}

.dropdown,
.dropbtn {
  padding-right: 40px;
}

.dropbtn:hover,
.dropbtn:focus {
  background-color: #2980b9;
  color: #ffffff;
}

.parentcontainer {
  position: relative;
  display: inline-block;
}

.dropdown {
  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 a {
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}

.dropdown ul {
  list-style: none;
  padding: 0;
  margin: 0;
  overflow: hidden;
  border-radius: 10px;
  z-index: 10;
}

.dropdown a:hover,
.dropdown a:active,
.dropdown a:focus {
  background-color: #0979ce;
  color: #ffffff;
}

.parentcontainer a:hover {
  background-color: #ddd;
}
.dropdown,
.dropbtn {
  position: relative;
}
.dropdown::before,
.dropbtn::before {
  content: '';
  position: absolute;
  right: 20px;
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
  border: 5px solid;
  border-top-color: rgba(0, 0, 0, 0);
  border-left-color: rgba(0, 0, 0, 0);
  margin-top: -2.5px;
  background-color: rgba(0, 0, 0, 0);
  transition: all ease-in-out 0.2s;
}
.dropdown {
  z-index: 10;
  position: relative;
}
.dropdown::before {
  z-index: -1;
  transform: rotate(-135deg);
  top: -4px;
  border-color: #ffffff;
  box-shadow: 1px 1px 4px -2px rgba(0, 0, 0, 0.4);
}
.dropdown-open .dropdown.dropdown-active {
  display: block;
}
.parentcontainer.dropdown-open .dropbtn {
  background-color: #0979ce;
  color: #ffffff;
}
.parentcontainer.dropdown-open .dropbtn:before {
  transform: rotate(-135deg);
}

JS

// Get all the dropdown menus from the document. Iterate over them and pass the function openDropDown as argument on each iteration
document.querySelectorAll('.dropbtn').forEach(openDropDown);
// Create the function to open the dropdown
function openDropDown(dropDown) {
  if (dropDown.classList.contains('on-dropdown') === true) {
    dropDown.addEventListener('click', function (e) {
      e.preventDefault();
      // if the other menu is open = has dropdown-active class then close this one
      if (
        this.nextElementSibling.classList.contains('dropdown-active') === true
      ) {
        // Close this dropdown
        this.parentElement.classList.remove('dropdown-open');
        this.nextElementSibling.classList.remove('dropdown-active');
      } else {
        // Otherwise - if this one has the dropdown-active class - close the open dropdown
        closeDropdown();

        // add the 'dropdown-open' class to this element's parent and 'dropdown-active' class to this element
        this.parentElement.classList.add('dropdown-open');
        this.nextElementSibling.classList.add('dropdown-active');
      }
    });
  }
}
// Create the function that closes the dropdown (removes the class 'dropdown-open' and 'dropdown-active' from the respective divs
function closeDropdown() {
  document.querySelectorAll('.parentcontainer').forEach(function (container) {
    container.classList.remove('dropdown-open');
  });
  document.querySelectorAll('.dropdown').forEach(function (menu) {
    menu.classList.remove('dropdown-active');
  });
}

// Closes the menu when the user clicks outside of the menu
window.addEventListener('click', function (e) {
  if (e.target.closest('.parentcontainer') === null) {
    closeDropdown();
  }
});
Related