mike
mike

Reputation: 67

click outside burger menu to close using javascript

I have been making a burger menu that works on desktop, opens and closes with an event listener.

It works fine but then i wanted to make it so that if the use clicked outside of the burger menu it also closes the menu.

I found a bit of java script that uses some logic to say that if not the navigation then close menu. it works when you click outside the menu but then the problem is that the toggle stops closing the menu.

I split my code up into two sections. The first code block is the code working with the toggle. The second block is the code that i'm using to try and make the click outside the menu work.

I think i have been staring at this for to long and cant seem to find a solution.

thanks in advance for any help.

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>

    <style>

a{
  color: #fff;
}

.ic-burger{
  width: 50px;
  height: 50px;
  background: #000;
  display: block;
  position: relative;
  z-index: 10;

}


.ic-nav ul {
    list-style: none;
    padding-left: 0px;
    display: flex;
    flex-direction: column;

    right: 0px;
    top: 0px;
    height: 100%;
    position: fixed;
    z-index: 5;
    overflow: auto;
    margin: 0px;
    padding-left: 20px;
    padding-right: 20px;

    }


html.ic-show .ic-nav:before{
  content: '';
  position: absolute;
top: 0;
left: auto;
right: 0;
bottom: 0;
    background-color: rgba(18,18,18,0.7);
z-index: 1;
width: 100%
}


.ic-second-level{
  opacity: 0;
  visibility: hidden;
  transition: all 200ms linear;
  padding: 0px;
  padding-top: 100px;
    background: #1e1e1e;

}

html.ic-show .ic-second-level{
  opacity: 1;
  visibility: visible;


}

    </style>

    <nav class="ic-nav">
  <!-- <div class="ic-burger-bkg"> -->
      <ul class="ic-burger-container">
        <li>
          <a href="javascript:void(0);" class="ic-burger" aria-expanded="false" aria-controls="menu" id="burger-icon">
            <div class="nav-icon">
            Burger <br>toggle
            </div>
          </a>
          <!-- ############ -->
          <ul class="ic-second-level" role="region" id="menu" aria-labeledby="burger-icon">
            <li class="top-li">
              <a href="/about/" class="">About</a>
            </li>
            <li class="top-li">
              <a href="/news/" class="">News</a>
            </li>

            <li class="top-li">
              <a href="/team/" class="">Team</a>
            </li>
            <li class="top-li">
              <a href="/contact/" class="">Contact</a>
            </li>
          </ul>
          <!-- ############ -->
        </li>
      </ul>
  <!-- </div> -->
    </nav>



  </body>


<script>
var documentElement = document.querySelector("html");
var sidebarIsOpen = () => documentElement.classList.contains("ic-show");


var openSidebar = () => {

documentElement.classList.add("ic-show");
};

var closeSidebar = () => {
documentElement.classList.remove("ic-show");
};


document.querySelector('.ic-burger').addEventListener("click", function() {
sidebarIsOpen() ? closeSidebar() : openSidebar();
  });




</script>



</html>

Here is the second bit of code i cant get to play friendly with the first.

  let sidebar = document.querySelector(".ic-second-level");

  document.addEventListener("mouseup", function(event){
    // If the event didn't originate from the open button or the sidebar, close it
    if(event.target !== sidebar && event.target !== openSidebar){
      closeSidebar();
    }
  });

these are the two sources ive used to help me https://dev.to/tongrhj/the-mistake-developers-make-when-coding-a-hamburger-menu-1deg Click Outside To close slide menu Javascript

Upvotes: 1

Views: 1656

Answers (1)

Peter Pan
Peter Pan

Reputation: 217

I am using event delegation to check if you click on the "ic-nav" element and then close it. Works like charm.

document.addEventListener('click',function(e){
    if(e.target && e.target.classList == 'ic-nav'){
        sidebarIsOpen() ? closeSidebar() : openSidebar();
     }
 });

var documentElement = document.querySelector("html");
var sidebarIsOpen = () => documentElement.classList.contains("ic-show");


var openSidebar = () => {

documentElement.classList.add("ic-show");
};

var closeSidebar = () => {
documentElement.classList.remove("ic-show");
};


document.querySelector('.ic-burger').addEventListener("click", function() {
    sidebarIsOpen() ? closeSidebar() : openSidebar();
});

 document.addEventListener('click',function(e){
    if(e.target && e.target.classList == 'ic-nav'){
        sidebarIsOpen() ? closeSidebar() : openSidebar();
     }
 });
a{
  color: #fff;
}

.ic-burger{
  width: 50px;
  height: 50px;
  background: #000;
  display: block;
  position: relative;
  z-index: 10;

}


.ic-nav ul {
    list-style: none;
    padding-left: 0px;
    display: flex;
    flex-direction: column;

    right: 0px;
    top: 0px;
    height: 100%;
    position: fixed;
    z-index: 5;
    overflow: auto;
    margin: 0px;
    padding-left: 20px;
    padding-right: 20px;

    }


html.ic-show .ic-nav:before{
  content: '';
  position: absolute;
top: 0;
left: auto;
right: 0;
bottom: 0;
    background-color: rgba(18,18,18,0.7);
z-index: 1;
width: 100%
}


.ic-second-level{
  opacity: 0;
  visibility: hidden;
  transition: all 200ms linear;
  padding: 0px;
  padding-top: 100px;
    background: #1e1e1e;

}

html.ic-show .ic-second-level{
  opacity: 1;
  visibility: visible;


}
<nav class="ic-nav">
  <!-- <div class="ic-burger-bkg"> -->
      <ul class="ic-burger-container">
        <li>
          <a href="javascript:void(0);" class="ic-burger" aria-expanded="false" aria-controls="menu" id="burger-icon">
            <div class="nav-icon">
            Burger <br>toggle
            </div>
          </a>
          <!-- ############ -->
          <ul class="ic-second-level" role="region" id="menu" aria-labeledby="burger-icon">
            <li class="top-li">
              <a href="/about/" class="">About</a>
            </li>
            <li class="top-li">
              <a href="/news/" class="">News</a>
            </li>

            <li class="top-li">
              <a href="/team/" class="">Team</a>
            </li>
            <li class="top-li">
              <a href="/contact/" class="">Contact</a>
            </li>
          </ul>
          <!-- ############ -->
        </li>
      </ul>
  <!-- </div> -->
    </nav>

Upvotes: 1

Related Questions