jollyjwhiskers
jollyjwhiskers

Reputation: 431

How do I make my responsive hamburger menu show up and hide with JS

I'm just trying to teach myself some (vanilla) Javascript at the moment, so I'm assuming this is probably a pretty basic question.

At the moment, I've already displayed and hidden the hamburger menu with CSS media queries, so when the page is loaded up for the first time, it works exactly as it should.

The problem:

After the JS script is run (on click) to open the hamburger menu and I widen my window again, the hamburger menu stays on the screen along with the nav that's supposed to show up past the breakpoint.

What I have tried is to use an if statement to basically do some sort of Javascript media query magic.

if (window.matchMedia('screen and (max-width: 48.62rem)').matches) {document.getElementById("mobile-nav").style.display = "block";
    } else{
        document.getElementById("mobile-nav").style.display = "none";
      };

What ends up happening is the same thing as before where the hamburger menu stays on screen if I go from a smaller window to a wider one BUT clicking it again makes it vanish. Good stuff, but now when I make my window smaller again, the menu has completely vanished.

I'm fairly new to JS, so what I understand is that the script is run, it overrides the css media queries and keeps the page like that. I'm thinking a loop might be my solution (maybe a while loop?), but I'm not really sure how to go about doing this.

Here's all the HTML, CSS and Javascript:

function openNav(){
    document.getElementById("mobile-nav").style.display = "none";
    document.getElementById("menu-items").style.width = "100%";
};
function closeNav(){
    document.getElementById("menu-items").style.width = "0";

    if (window.matchMedia('screen and (max-width: 48.62rem)').matches) {document.getElementById("mobile-nav").style.display = "block";
    } else{
        document.getElementById("mobile-nav").style.display = "none";
    };
    
};
 #nav {
    display: none;
  }
  
#mobile-nav{
  float:right;
}
.open-nav {
  display:block;
  cursor: pointer;
  margin: 0.5rem 4rem 0 0;
  font-size: 35px;
  line-height: 70px;
}

.menu-items{
  text-align: center;
  width: 0%;
  overflow-x: hidden;
  height: 100vh;
  z-index: 50;
  position:fixed;
  background: rgba(24,24,24,0.9);
  transition:0.5s;
  display:block;
}

.menu-items a{
  clear:right;
  display:block;
  font-size: 1.25;
  padding:1em 0;
  transition:0.3s
}

.close-nav{
  float:right;
  margin:0.5rem 1em 0 0;
  font-size: 50px;
  color:rgb(206, 206, 206);
}



/* Media Queries*/
@media (min-width: 48.6rem) {
  /* Nav */
  #nav-bar{
    display:flex;
  }
  #nav {
    float:right;
    margin:0 5rem 0 0;
    display: flex;
  }

  #nav li {
    margin-right: 1em;
  }

  #mobile-nav {
    display: none;
  }
<div id="menu-items" class="menu-items">
        <a href="javascript:void(0)" class="close-nav" onclick="closeNav()">&times;</a>
        <a href="#section1" class="link lt-txt">...</a>
        <a href="#" class="link lt-txt">...</a>
        <a href="#" class="link lt-txt">...</a>
      </div>
      <nav id="nav-bar">
          <!--LOGO-->
          <div id="logo"><img src="./img/logo.png" alt="" /></div>
          <!--Mobile Nav-->
          <div id="mobile-nav">
            <span class="open-nav" onclick="openNav()">&#9776;</span>
          </div>

          <!--Main Nav-->
          <ul id="nav">
            <li>
              <a href="#section1" class="link">...</a>
            </li>
            <li>
              <a href="#" class="link">...</a>
            </li>
            <li>
              <a href="#" class="link">...</a>
            </li>
          </ul>
        </nav>

Upvotes: 1

Views: 2996

Answers (1)

robinvrd
robinvrd

Reputation: 1848

Toggling CSS classes is way more cleaner and easier than using JavaScript style attribute. You should use it that way :

var btn = document.querySelector("#responsive-menu");
var nav = document.querySelector("nav");

btn.onclick = function() {
  nav.classList.toggle("expand");
}
nav {
  display: none;  
  background-color: #ed0;
}

nav.expand {
  display: block;
}
<button id="responsive-menu">Click me</button>
<nav>
  Menu
</nav>

And to specify different CSS for some media size, use CSS media queries.

Upvotes: 1

Related Questions