ccase3
ccase3

Reputation: 27

Clicking the screen to close an off canvas menu

I am using a off canvas menu similar to the one on W3 Schools by having two functions called to toggle the menu on/off using onclick. I am wanting to add in a function to be able to close the menu by clicking anywhere on the screen. I am new to Javascript and do not know how to be able to implement this. Any help would be great! Thanks!

function openNav() {
  document.getElementById("mySidenav").style.width = "250px";
  document.getElementById("main").style.marginLeft = "250px";
  document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
}

function closeNav() {
  document.getElementById("mySidenav").style.width = "0";
  document.getElementById("main").style.marginLeft= "0";
  document.body.style.backgroundColor = "white";
}
body {
  font-family: "Lato", sans-serif;
  transition: background-color .5s;
}

.sidenav {
  height: 100%;
  width: 0;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: #111;
  overflow-x: hidden;
  transition: 0.5s;
  padding-top: 60px;
}

.sidenav a {
  padding: 8px 8px 8px 32px;
  text-decoration: none;
  font-size: 25px;
  color: #818181;
  display: block;
  transition: 0.3s;
}

.sidenav a:hover {
  color: #f1f1f1;
}

.sidenav .closebtn {
  position: absolute;
  top: 0;
  right: 25px;
  font-size: 36px;
  margin-left: 50px;
}

#main {
  transition: margin-left .5s;
  padding: 16px;
}

@media screen and (max-height: 450px) {
  .sidenav {padding-top: 15px;}
  .sidenav a {font-size: 18px;}
}
<body>

<div id="mySidenav" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<div id="main">
  <h2>Sidenav Push Example</h2>
  <p>Click on the element below to open the side navigation menu, and push this content to the right. Notice that we add a black see-through background-color to body when the sidenav is opened.</p>
  <span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; open</span>
</div>
</body>

Upvotes: 2

Views: 1181

Answers (3)

EarthCow
EarthCow

Reputation: 67

I have spent a lot of time on this and the following will work:

window.onclick = function(event){if(event.target == document.getElementById('outerNav')){closeNav();}};

function openNav() {
    document.getElementById("outerNav").style.display = "block";
    document.getElementById("mySidenav").style.transition = "0.5s";//I try to add the transition again. But it still doesn't display
    document.getElementById("mySidenav").style.width = "250px";
    document.getElementById("main").style.marginLeft = "250px";
    document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
}

function closeNav() {
    document.getElementById("mySidenav").style.width = "0";
    document.getElementById("main").style.marginLeft= "0";
    document.body.style.backgroundColor = "white";
    setTimeout(function(){
        document.getElementById("outerNav").style.display = "none";
    },500);
}
body {
    font-family: "Lato", sans-serif;
    transition: background-color .5s;
}

.sidenav {
    height: 100%;
    width: 0;
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    background-color: #111;
    overflow-x: hidden;
    transition: 0.5s;
    padding-top: 60px;
}

.sidenav a {
    padding: 8px 8px 8px 32px;
    text-decoration: none;
    font-size: 25px;
    color: #818181;
    display: block;
    transition: 0.3s;
}

.sidenav a:hover {
    color: #f1f1f1;
}

.sidenav .closebtn {
    position: absolute;
    top: 0;
    right: 25px;
    font-size: 36px;
    margin-left: 50px;
}

#main {
    transition: margin-left .5s;
    padding: 16px;
}

@media screen and (max-height: 450px) {
    .sidenav {padding-top: 15px;}
    .sidenav a {font-size: 18px;}
}.outerNav {
    display:none;
    position:fixed;
    left:0;
    top:0;
    width:100%;
    height:100%;
    overflow:hidden;
    background-color:transparent;
}
<body>
    <div id="outerNav" class="outerNav">
        <div id="mySidenav" class="sidenav">
            <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
            <a href="#">About</a>
            <a href="#">Services</a>
            <a href="#">Clients</a>
            <a href="#">Contact</a>
        </div>
    </div>
    <div id="main">
        <h2>Sidenav Push Example</h2>
        <p>Click on the element below to open the side navigation menu, and push this content to the right. Notice that we add a black see-through background-color to body when the sidenav is opened.</p>
        <span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; open</span>
    </div>
</body>
The only thing that I couldn't figure out was why there was no transition in the beginning. I realize that the transition is a big deal but maybe there is a way to get the transition to work.

Upvotes: 3

gui3
gui3

Reputation: 1867

as suggested by Matt U, you need to call closeNav on click on your main element by adding this in the html :

...
<div id="main" onclick="closeNav()">
...

But you also need to stop the click to propagate (event bubbling) because if not, when you try to open the menu by clicking the button, the click bubbles to the main div and immediately closes the menu...

so you need to add these lines to your javascript

document.getElementById("button")
  .addEventListener("click", event => {
    event.stopPropagation();
  }
)

and an ID to the button

 <span id="button" ...

here is a working example https://codepen.io/gui3/pen/mddogVj?editors=1010

Upvotes: 3

Matt U
Matt U

Reputation: 46

Run your closeNav(); function on your main element. That way, if the user clicks off of the menu, the close function is triggered.

Upvotes: 0

Related Questions