0

I'm trying to mimic android's side menu style. here is the link to my codepen https://codepen.io/Killerbee98/pen/KqreZw. My problem is that it doesn't close when i press outside of the navigation as it does on android. Now i have done some research on how to do smth like this; first would be to use:

$('#menucontainer').click(function(event){
  event.stopPropagation();
});

but this isn't a practical method and is wrong to use.

Second would be to add a click listener using :

$(document).click(function(event){ 
  if (!$(event.target).closest('.navigation').length) {
    $('.navigation').hide();
  }
});

But this doesn't work with my code since my code has a click listener:

$('.menu-btn').click(function() {
   console.log("button pressed");
   if($('.navigation').width() === 250){
   $('.navigation').width('0px');
}else{
   $('.navigation').width('250px');
  }
})

i tried doing this:

$('.menu-btn').click(function() {
   console.log("button pressed");
   if($('.navigation').width() === 250){
   $('.navigation').width('0px');
   $(document).click(function(event){ 
       if (!$(event.target).closest('.navigation').length) {
           $('.navigation').hide();
       }
   });
 }else{
   $('.navigation').width('250px');
  }
})

it closes but doesn't open back again as it should.

how do i go about solving my issue?

  • Possible duplicate of [How do I detect a click outside an element?](https://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element) – Kukic Vladimir Jul 10 '17 at 23:57
  • @Kukic Vladimir i know and have read those posts but i want to avoid using the stopPropagation method. What you answered worked for me and i have done it but any other way without using the mentiond event method? – comounburro Jul 11 '17 at 00:03
  • did you check this [answer](https://stackoverflow.com/a/3028037/2744511) on the same post. People are saying that it working as expected – Kukic Vladimir Jul 11 '17 at 00:06

3 Answers3

0

I Have managed to make a working example by using this answer

Here is the code

 $('.menu-btn').click(function() {
     if($('.navigation').is(":visible")) {
            $('.navigation').hide();
        } else {
           $('.navigation').show();
        }
})

$(document).click(function(event) { 
    if(!$(event.target).closest('.navigation').length &&      
    !$(event.target).hasClass('menu-btn')) {
        if($('.navigation').is(":visible")) {
            $('.navigation').hide();
        }
    }        
})

EDIT:

Also I Have adjusted css style for navigation class

.navigation{
  position:fixed;
  left: 0;
  top: 0;
  width: 250px;
  display: none;
  height: 100%;
  box-shadow: 1px 0px 15px 0px #999;
  transition: .2s;
}

Here is a working demo

Kukic Vladimir
  • 1,010
  • 4
  • 15
  • 22
0

The only changes you need to your EXISTING code is to add the same styles for both the button click event and the document click event.

$('.menu-btn').click(function() {
  event.stopPropagation();
  console.log("button pressed");
  if ($('.navigation').width() === 250) {
    $('.navigation').hide();
    $('.navigation').width('0px');
  } else {
    $('.navigation').show();
    $('.navigation').width('250px');
  }
})
$(document).click(function(event) {
  if (!$(event.target).closest('.navigation').length) {
    $('.navigation').hide();
    $('.navigation').width('0px');
    event.stopPropagation();
  }
});
* {
  margin: 0;
  padding: 0;
}

.navigation {
  position: fixed;
  left: 0;
  top: 0;
  width: 0;
  height: 100%;
  box-shadow: 1px 0px 15px 0px #999;
  transition: .2s;
  display: none;
}

.header-image {
  height: 150px;
  background: yellow;
  margin-bottom: 5px;
}

ul {
  list-style-type: none;
}

ul li {
  display: inline-block;
  width: 100%;
  background: #eee;
}

ul li a {
  display: block;
  width: 100%;
  height: 50px;
}

.clearfix:after {
  content="";
  display: table;
  clear: both;
}

.menu-btn {
  height: 50px;
  width: 50px;
  background: none;
  border: none;
  cursor: pointer;
  outline: none;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 100;
}

.bar {
  display: block;
  position: absolute;
  width: 30px;
  height: 2px;
  background: black;
  left: 10px;
  right: 10px;
}

.bar:before,
.bar:after {
  display: block;
  content: "";
  left: 0;
  width: 100%;
  background-color: black;
  position: absolute;
  height: 2px;
  transition: .15s ease-in-out;
}

.bar:before {
  top: -10px;
}

.bar:after {
  top: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="menu-btn">
  <span class="bar"></span>
</button>
<div class="navigation">
  <div class="header-image"></div>
  <ul>
    <div class="link">
      <li>
        <a href=""></a>
      </li>
    </div>
    <div class="link">
      <li>
        <a href=""></a>
      </li>
    </div>
    <div class="link">
      <li>
        <a href=""></a>
      </li>
    </div>
    <div class="link">
      <li>
        <a href=""></a>
      </li>
    </div>
  </ul>
</div>
  • event.stopPropagation(); works without anything extra... the challenge is not to use it and still be able to have animation. @Kukic Vladimir's code works great but at the cost of losing the animation. – comounburro Jul 11 '17 at 00:58
0

Thanks to @Kukic Vladimir's solution, it works with a bit of change in the JS code he provided.

$('.menu-btn').click(function() {
 if($('.navigation').width() === 0) {
        $('.navigation').width('250px');
    } else {
       $('.navigation').width('0px');
    }
});
$(document).click(function(event) { 
    if(!$(event.target).closest('.navigation').length &&      
!$(event.target).hasClass('menu-btn')) {
    if($('.navigation').width('250px')) {
        $('.navigation').width('0px');
    }
 }        
})