S.Detta
S.Detta

Reputation: 3

HTML/CSS/Javascript: Open/Close Menu when Clicking Button

I've got a hamburger icon for my page that should open/close a dropdown menu when clicked on. I pulled the code for the hamburger icon from Jonathan Suh's github page and am trying to implement a open/close dropdown menu with it (here's the page for your reference https://github.com/jonsuh/hamburgers).

The problem is that when I click on it, the dropdown menu will appear, but when I click on it again it won't disappear. I've tried a few things, such as setting a boolean variable to false and making it true when clicked on, but the code doesn't execute the way I imagine it would. Here's the Code:

//declarations
var hamburger = document.querySelector(".hamburger");

function dropDown() {
  document.querySelector(".dropdown-content").style.display = "block";

}

hamburger.addEventListener("click", function() {
  hamburger.classList.toggle("is-active");
  dropDown();
});
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  display: none;
  position: absolute;
  z-index: 1;
}

.dropdown-content a {
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}

.show {
  display: block;
}


/*!
 * Hamburgers
 * @description Tasty CSS-animated hamburgers
 * @author Jonathan Suh @jonsuh
 * @site https://jonsuh.com/hamburgers
 * @link https://github.com/jonsuh/hamburgers
 */

.hamburger {
  padding: 15px 15px;
  display: inline-block;
  cursor: pointer;
  transition-property: opacity, filter;
  transition-duration: 0.15s;
  transition-timing-function: linear;
  font: inherit;
  color: inherit;
  text-transform: none;
  background-color: transparent;
  border: 0;
  margin: 0;
  overflow: visible;
}

.hamburger:hover {
  opacity: 0.7;
}

.hamburger-box {
  width: 40px;
  height: 24px;
  display: inline-block;
  position: relative;
}

.hamburger-inner {
  display: block;
  top: 50%;
  margin-top: -2px;
}

.hamburger-inner,
.hamburger-inner::before,
.hamburger-inner::after {
  width: 40px;
  height: 4px;
  background-color: #000;
  border-radius: 4px;
  position: absolute;
  transition-property: transform;
  transition-duration: 0.15s;
  transition-timing-function: ease;
}

.hamburger-inner::before,
.hamburger-inner::after {
  content: "";
  display: block;
}

.hamburger-inner::before {
  top: -10px;
}

.hamburger-inner::after {
  bottom: -10px;
}


/*
   * Spring
   */

.hamburger--spring .hamburger-inner {
  top: 2px;
  transition: background-color 0s 0.13s linear;
}

.hamburger--spring .hamburger-inner::before {
  top: 10px;
  transition: top 0.1s 0.2s cubic-bezier(0.33333, 0.66667, 0.66667, 1), transform 0.13s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}

.hamburger--spring .hamburger-inner::after {
  top: 20px;
  transition: top 0.2s 0.2s cubic-bezier(0.33333, 0.66667, 0.66667, 1), transform 0.13s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}

.hamburger--spring.is-active .hamburger-inner {
  transition-delay: 0.22s;
  background-color: transparent;
}

.hamburger--spring.is-active .hamburger-inner::before {
  top: 0;
  transition: top 0.1s 0.15s cubic-bezier(0.33333, 0, 0.66667, 0.33333), transform 0.13s 0.22s cubic-bezier(0.215, 0.61, 0.355, 1);
  transform: translate3d(0, 10px, 0) rotate(45deg);
}

.hamburger--spring.is-active .hamburger-inner::after {
  top: 0;
  transition: top 0.2s cubic-bezier(0.33333, 0, 0.66667, 0.33333), transform 0.13s 0.22s cubic-bezier(0.215, 0.61, 0.355, 1);
  transform: translate3d(0, 10px, 0) rotate(-45deg);
}
  <div class="dropDown">
    <button onclick="dropDown()" class="hamburger hamburger--spring" type="button">
        <span class = "hamburger-box">
            <span class="hamburger-inner"></span>
        </span>
        <div id="myDropDown" class="dropdown-content">
            <a href="home.html">Home</a>
            <a href="work.html">Work</a>
            <a href="resume.html">Resume</a>
            <a href="life.html">Life</a>
        </div>
    </button>
  </div>

While I know there is probably a solution you can use in jQuery, I have no experience with that. So please, keep it in JavaScript. I am completely new to it, but have a basic understanding of how it works.

Upvotes: 0

Views: 5062

Answers (3)

TravorLZH
TravorLZH

Reputation: 302

Try to do some css like the one in my website

I use the code to monitor the attribute. You can use JS to change the attribute of the dropdown-content element.

So, put the following into your CSS

.dropdown-content[show='true']{
    position: absolute;
    margin-top: 50px;
    display: block;
 }

Then change your JavaScript function to this:

function dropDown(){
    var drop=document.getElementById("myDropdown");
    if(drop.getAttribute("show")=="true"){
        drop.setAttribute("show","false");
    }else{
        drop.setAttribute("show","true");
    }
}

For security, I suggest you to add show="false" to your dropdown-content element. You can also refer my website code to understand them more.

Upvotes: 0

Carl Edwards
Carl Edwards

Reputation: 14434

No need for dropDown() or any additional JS for that matter. Your current click event handler will do just fine. Just add a descendant selector in your CSS that targets dropdown-content when .hamburger also has the class of .is-active (which is already being handled through your class toggle):

.hamburger.is-active .dropdown-content {
  display: block;
}

Upvotes: 1

Ele
Ele

Reputation: 33726

Try this:

function dropDown() {
    var dropDown = document.querySelector(".dropdown-content");
    if (dropDown.style.display === 'block') {
        dropDown.style.display = "none";
    } else {
        dropDown.style.display = 'block'
    }
}

Upvotes: 1

Related Questions