javascript - stopPropagation issue when trying to detect second click on checkbox

77 views Asked by At

I'm trying to get a hamburger menu to open a div when click and also close when clicked a second time when the hamburger is in the (X) state.

I've added in code that allows user to close the hamburger also when they click out side the div that opens. However the stopPropagation stops the hamburger being clicked twice and I believe

else {
    $(".NavMenu").hide();
 }

Isn't being detected.

Is there a simpler way to do this or a solution to get it to work without stopPropagation?

$('#burger').click(function(event) {
  event.stopPropagation();
  if ($(this).is(':checked')) {
    $(".NavMenu").show();
  } else {
    $(".NavMenu").hide();
  }
});

$('body').click(function() {
  if ($('#burger').is(':checked')) {
    $(".NavMenu").hide();
    $("#burger").prop("checked", false);
  }
})

$('.NavMenu').click(function(event) {
  event.stopPropagation();
})
.mobileMenu {
  display: block;
  width: 30px;
  height: 70px;
  float: left;
}

.NavMenu {
  display: none;
  position: absolute;
  width: 100%;
  height: 50px;
  top: 70px;
  background-color: #FFF;
  margin-left: -15px;
  padding: 15px;
  border-bottom: 1px solid #CCC;
}

input+label {
  position: fixed;
  top: 26px;
  left: 30px;
  height: 20px;
  width: 15px;
  z-index: 5;
}

input+label span {
  position: absolute;
  width: 100%;
  height: 2px;
  top: 50%;
  margin-top: -1px;
  left: 0;
  display: block;
  background: #020304;
  transition: .5s;
}

input+label span:first-child {
  top: 3px;
}

input+label span:last-child {
  top: 16px;
}

label:hover {
  cursor: pointer;
}

input:checked+label span {
  opacity: 0;
  top: 50%;
}

input:checked+label span:first-child {
  opacity: 1;
  transform: rotate(405deg);
}

input:checked+label span:last-child {
  opacity: 1;
  transform: rotate(-405deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="burger" type="checkbox" style="display:none;" />

<label for="burger">
    <span></span>
    <span></span>
    <span></span>
</label>
<div class="NavMenu">
  <a href="https://google.com" target="_blank">Check accessibility</a>
</div>


<div style="margin-top:70px;height: 500px; background-color:#F00;">

</div>

http://jsfiddle.net/nzrvwfap/

2

There are 2 answers

10
Mosh Feu On BEST ANSWER

You can check on body click if you click on any span of the hamburger and ignore it.

$('#burger').click(function(event) {
  event.stopPropagation();
  if ($(this).is(':checked')) {
    $(".NavMenu").show();
  } else {
    $(".NavMenu").hide();
  }
});

$('body').click(function(e) {
  if ($(e.target).is($('.hamburger-trigger span'))) {
    return;
  }
  if ($('#burger').is(':checked')) {
    $(".NavMenu").hide();
    $("#burger").prop("checked", false);
  }
})

$('.NavMenu').click(function(event) {
  event.stopPropagation();
})
.mobileMenu {
  display: block;
  width: 30px;
  height: 70px;
  float: left;
}

.NavMenu {
  display: none;
  position: absolute;
  width: 100%;
  height: 50px;
  top: 70px;
  background-color: #FFF;
  margin-left: -15px;
  padding: 15px;
  border-bottom: 1px solid #CCC;
}

input+label {
  position: fixed;
  top: 26px;
  left: 30px;
  height: 20px;
  width: 15px;
  z-index: 5;
}

input+label span {
  position: absolute;
  width: 100%;
  height: 2px;
  top: 50%;
  margin-top: -1px;
  left: 0;
  display: block;
  background: #020304;
  transition: .5s;
}

input+label span:first-child {
  top: 3px;
}

input+label span:last-child {
  top: 16px;
}

label:hover {
  cursor: pointer;
}

input:checked+label span {
  opacity: 0;
  top: 50%;
}

input:checked+label span:first-child {
  opacity: 1;
  transform: rotate(405deg);
}

input:checked+label span:last-child {
  opacity: 1;
  transform: rotate(-405deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="burger" type="checkbox" style="display:none;" />

<label class="hamburger-trigger" for="burger">
    <span></span>
    <span></span>
    <span></span>
</label>
<div class="NavMenu">
  <a href="https://google.com" target="_blank">Check accessibility</a>
</div>


<div style="margin-top:70px;height: 500px; background-color:#F00;">

</div>

Important

But, if you are using with checkbox, I recommend you to try to do this with css only using ~ selector.

.mobileMenu {
  display: block;
  width: 30px;
  height: 70px;
  float: left;
}

.NavMenu {
  display: none;
  position: absolute;
  width: 100%;
  height: 50px;
  top: 70px;
  background-color: #FFF;
  margin-left: -15px;
  padding: 15px;
  border-bottom: 1px solid #CCC;
}

/* add this */
#burger:checked ~ .NavMenu {
  display: block;
}

input+label {
  position: fixed;
  top: 26px;
  left: 30px;
  height: 20px;
  width: 15px;
  z-index: 5;
}

input+label span {
  position: absolute;
  width: 100%;
  height: 2px;
  top: 50%;
  margin-top: -1px;
  left: 0;
  display: block;
  background: #020304;
  transition: .5s;
}

input+label span:first-child {
  top: 3px;
}

input+label span:last-child {
  top: 16px;
}

label:hover {
  cursor: pointer;
}

input:checked+label span {
  opacity: 0;
  top: 50%;
}

input:checked+label span:first-child {
  opacity: 1;
  transform: rotate(405deg);
}

input:checked+label span:last-child {
  opacity: 1;
  transform: rotate(-405deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="burger" type="checkbox" style="display:none;" />

<label class="hamburger-trigger" for="burger">
    <span></span>
    <span></span>
    <span></span>
</label>
<div class="NavMenu">
  <a href="https://google.com" target="_blank">Check accessibility</a>
</div>


<div style="margin-top:70px;height: 500px; background-color:#F00;">

</div>

4
Sablefoste On

To allow it to open again, simply change the line:

$('body').click(function() {

to

$('body').not('#burger').click(function() {