javascriptsidenav

JS - Opening Sub Nav while Closing previously opened Sub-Nav


I'm just starting Javascript and I'm trying to get a sub-menu of a side Nav to preform two functions (open desired sub-menu while closing any currently open sub-menu)

This is the current state of things:

https://jsfiddle.net/dangeruss/r67Lzpnh/5/

I was thinking about:

function toggleNav() {
var element = document.getElementById("mySidenav2");
if (element.style.width == "250px") {
    element.style.width = "0px";
} else {
    element.style.width = "250px";
}

But i'm un-sure how to close any sidenave open (mySidenavX) and open mySidenav3 etc.


Solution

  • As epascarello mentioned in the comments, you can use classes to amalgamate functionality and make your code easier.

    For example, you have two sub-navs. Give them the same class, and use that to do the same operation on both, either at once or individually. As for closing "the other" open sideNav, there is no need to know which one is open - just close them all, via the className, and then open the one you want.

    Here is your updated jsFiddle with these changes.

    function openMainNav() {
      document.getElementById("myMainNav").classList.add('sideNavOpen');
      document.getElementById("main").classList.add('lmarg250');
    }
    function openSubNav(num) {
      closeSubNavs();
      document.getElementById("mySidenav"+num).classList.add('sideNavOpen');
      document.getElementById("main").classList.add('lmarg500');
    }
    function closeMainNav() {
      closeSubNavs();
      document.getElementById("myMainNav").classList.remove('sideNavOpen');
      document.getElementById("main").classList.remove('lmarg250');
      document.getElementById("main").classList.remove('lmarg500');
    }
    function closeSubNavs() {
      let subs = document.querySelectorAll(".sub-sidenav");
      subs.forEach( (el) => {
      	el.classList.remove('sideNavOpen');
      });
    }
    body {font-family: "Lato", sans-serif;}
        .main-sidenav {
          height: 100%;
          width: 0;
          z-index: 1;
          top: 0;
          left: 0;
          background-color: #111;
          overflow-x: hidden;
          transition: 0.5s;
          padding-top: 60px;
          position:absolute;
        }
        .sub-sidenav {
          height: 100%;
          width: 0;
          position: fixed;
          z-index: 1;
          top: 0;
          left: 0;
          background-color: rgb(153, 4, 141);
          overflow-x: hidden;
          transition: 0.5s;
          padding-top: 60px;
          margin-left: 250px;
          z-index:10;
        }
        
        .lmarg250 {margin-left:250px;}
        .lmarg500 {margin-left:500px;}
        .sideNavOpen{width:250px;}
        .main-sidenav a, .sub-sidenav a {
          padding: 8px 8px 8px 32px;
          text-decoration: none;
          font-size: 25px;
          color: #818181;
          display: block;
          transition: 0.3s;
        }
        
        .main-sidenav span, .sub-sidenav span {
          padding: 8px 8px 8px 32px;
          text-decoration: none;
          font-size: 25px;
          color: #818181;
          display: block;
          transition: 0.3s;
        }
    
        .main-sidenav a:hover, .sub-sidenav a:hover {
          color: #f1f1f1;
        }
    
        .main-sidenav .closebtn, .sub-sidenav .closebtn {
          position: absolute;
          top: 0;
          right: 25px;
          font-size: 36px;
          margin-left: 50px;
        }    
        
        @media screen and (max-height: 450px) {
          .sidenav {padding-top: 15px;}
          .sidenav a {font-size: 18px;}
        }
    <div id="myMainNav" class="main-sidenav">
      <a onclick="closeMainNav()" href="javascript:void(0)" class="closebtn">&times;</a>
      <span onclick="openSubNav(2)" style="font-size:30px;cursor:pointer">Starters</span>
      <span onclick="openSubNav(3)" style="font-size:30px;cursor:pointer">Snacks</span>
      <a href="#">Omelet</a>
      <a href="#">American Favorites</a>
      <a href="#">Burgers</a>
      <a href="#">Hot Dogs</a>
      <a href="#">Sandwich / Wrap</a>
      <a href="#">Salads</a>
      <a href="#">Kids Menu</a>
      <a href="#">Extras</a>
      <a href="#">Drinks</a>
      <a href="#">Beer & Wine</a>
      <a href="#">Cocktails</a>
      <a href="#">Milkshakes</a>
      <a href="#">Desserts</a>
      <a href="#">Waffles etc.</a>
      <a href="#">Coffee</a>
    
    </div>
    
    <div id="mySidenav2" class="sub-sidenav">
      <a onclick="closeSubNavs()" href="javascript:void(0)" class="closebtn2">&times;</a>
      <a href="munchie.html">Starters</a>
      <a href="#">Cheeses</a>
      <a href="#">Meats</a>
      <a href="#">Dips</a>
    </div>
    
    <div id="mySidenav3" class="sub-sidenav">
      <a onclick="closeSubNavs()" href="javascript:void(0)" class="closebtn2">&times;</a>
      <a href="munchie.html">Snacks</a>
      <a href="#">Cheesie</a>
      <a href="#">Chips</a>
      <a href="#">Popcorn</a>
    </div>
    
    <div id="main">
      <h2>Website</h2>
      <p>This is a site made by spider-webs</p>
      <span onclick="openMainNav()" style="font-size:30px;cursor:pointer">&#9776; open</span>
    </div>

    Update:

    Updated to add calls to closeSubNavs() when closing the mainMenu, and when opening any subNav. When closing the main sideNav, you probably also want to close any sub-sideNavs that remain open, yes? Also, before opening any subNav, call closeSubNavs() to close any others that are open. Apologies for forgetting that step.

    StackSnippet updated above. Here is the link to the updated jsFiddle.