Search code examples
javascriptonclicksidebar

Close sidebar menu when click outside of it and when click on menu item


The target is to close the sidebar menu when I click outside of it or when I click on one of the menu item. I've created the two working functions in Javascript to open and close the menu, clicking on the toggle:

function openNav() {
  document.getElementById("#sideMenu").style.width = "250px";
}

function closeNav() {
  document.getElementById("#sideMenu").style.width = "0";
}

function clickOutsite() {
  TO - DO
}

function clickOnItemAndClose() {
  TO - DO
}
<div class="header"></div>
<input type="checkbox" class="openSideMenu" id="openSideMenu">
<label for="openSideMenu" class="sideIconToggle" onclick="openNav()">
            <div class="spinner diagonal part-1"></div>
            <div class="spinner horizontal"></div>
            <div class="spinner diagonal part-2"></div>
            </label>
<div id="sideMenu">
  <ul class="sideMenuInner">
    <li class="active"><a href="#" data-toggle="tab">Item1</a></li>
    <li><a href="#" data-toggle="tab">Item2</a></li>
    <li><a href="#" data-toggle="tab">Item3</a></li>
  </ul>
</div>

I've tried to create an overlay layer and create a function connected to it, but the result is not valid.

Could you help me, please? Thanks in advance

Edit: here there is a demo https://codepen.io/Clara83/pen/PoPVMgN


Solution

  • The whole animation of hide/show is based off CSS so you just need to toggle the checked property of the checkbox <input type="checkbox" class="openSideMenu" id="openSideMenu">

    To solve the problem of detecting click outside you can wrap the sidebar in a div and then use contains property of event object that gets emitted from the element being clicked

    function hideSidebar() {
      document.getElementById('openSideMenu').checked = false;
    }
    
    var sideIconToggle = document.getElementById('sidebarContainer');
    
    document.addEventListener('click', function(event) {
      if (!sidebarContainer.contains(event.target))
        hideSidebar();
    });
    html,
    body {
      overflow-x: hidden;
      height: 100%;
    }
    
    body {
      background: #fff;
      padding: 0;
      margin: 0;
      font-family: 'Varela Round', sans-serif;
    }
    
    .header {
      display: block;
      margin: 0 auto;
      width: 100%;
      max-width: 100%;
      box-shadow: none;
      background-color: black;
      position: fixed;
      height: 60px!important;
      overflow: hidden;
      z-index: 10;
    }
    
    .main {
      margin: 0 auto;
      display: block;
      height: 100%;
      margin-top: 60px;
    }
    
    .mainInner {
      display: table;
      height: 100%;
      width: 100%;
      text-align: center;
    }
    
    .mainInner div {
      display: table-cell;
      vertical-align: middle;
      font-size: 3em;
      font-weight: bold;
      letter-spacing: 1.25px;
    }
    
    #sideMenu {
      height: 100%;
      position: fixed;
      left: 0;
      width: 250px;
      margin-top: 60px;
      transform: translateX(-250px);
      transition: transform 250ms ease-in-out;
      background: grey;
      z-index: 1;
    }
    
    .sideMenuInner {
      margin: 0;
      padding: 0;
      border-top: 1px solid black;
    }
    
    .sideMenuInner li {
      list-style: none;
      color: #fff;
      text-transform: uppercase;
      font-weight: bold;
      padding: 20px;
      cursor: pointer;
      border-bottom: 1px solid black;
    }
    
    .sideMenuInner li span {
      display: block;
      font-size: 14px;
      color: rgba(255, 255, 255, 0.50);
    }
    
    .sideMenuInner li a {
      color: #fff;
      text-transform: uppercase;
      font-weight: bold;
      cursor: pointer;
      text-decoration: none;
    }
    
    input[type="checkbox"]:checked~#sideMenu {
      transform: translateX(0);
    }
    
    input[type=checkbox] {
      transition: all 0.3s;
      box-sizing: border-box;
      display: none;
    }
    
    .sideIconToggle {
      transition: all 0.3s;
      box-sizing: border-box;
      cursor: pointer;
      position: absolute;
      z-index: 99;
      height: 100%;
      width: 100%;
      top: 22px;
      left: 15px;
      height: 22px;
      width: 22px;
    }
    
    .spinner {
      transition: all 0.3s;
      box-sizing: border-box;
      position: absolute;
      height: 3px;
      width: 100%;
      background-color: #fff;
    }
    
    .horizontal {
      transition: all 0.3s;
      box-sizing: border-box;
      position: relative;
      float: left;
      margin-top: 3px;
    }
    
    .diagonal.part-1 {
      position: relative;
      transition: all 0.3s;
      box-sizing: border-box;
      float: left;
    }
    
    .diagonal.part-2 {
      transition: all 0.3s;
      box-sizing: border-box;
      position: relative;
      float: left;
      margin-top: 3px;
    }
    
    input[type=checkbox]:checked~.sideIconToggle>.horizontal {
      transition: all 0.3s;
      box-sizing: border-box;
      opacity: 0;
    }
    
    input[type=checkbox]:checked~.sideIconToggle>.diagonal.part-1 {
      transition: all 0.3s;
      box-sizing: border-box;
      transform: rotate(135deg);
      margin-top: 8px;
    }
    
    input[type=checkbox]:checked~.sideIconToggle>.diagonal.part-2 {
      transition: all 0.3s;
      box-sizing: border-box;
      transform: rotate(-135deg);
      margin-top: -9px;
    }
    
    #sidenav-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 0;
      height: 100%;
      background: rgba(0, 0, 0, .1);
      cursor: pointer;
      z-index: 1;
    }
    <div class="header"></div>
    
    <div id="sidebarContainer">
      <input type="checkbox" class="openSideMenu" id="openSideMenu">
    
      <label for="openSideMenu" class="sideIconToggle">
        <div class="spinner diagonal part-1"></div>
        <div class="spinner horizontal"></div>
        <div class="spinner diagonal part-2"></div>
      </label>
    
      <div id="sideMenu">
        <ul class="sideMenuInner">
          <li class="active" onclick="hideSidebar()"><a href="#" data-toggle="tab">Item1</a></li>
          <li onclick="hideSidebar()"><a href="#" data-toggle="tab">Item2</a></li>
          <li onclick="hideSidebar()"><a href="#" data-toggle="tab">Item3</a></li>
        </ul>
      </div>
    </div>