javascript — проблема stopPropagation при попытке обнаружить второй щелчок по флажку

Я пытаюсь заставить меню гамбургера открывать div при нажатии, а также закрывать при нажатии во второй раз, когда гамбургер находится в состоянии (X).

Я добавил код, который позволяет пользователю закрывать гамбургер также, когда он щелкает за пределами открывающегося элемента div. Однако stopPropagation останавливает двойной щелчок по гамбургеру, и я верю

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

Не обнаруживается.

Есть ли более простой способ сделать это или решение, чтобы заставить его работать без 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/


person Community    schedule 31.08.2017    source источник
comment
Нужно ли использовать флажок для отслеживания состояния?   -  person brian17han    schedule 31.08.2017
comment
@brian17han да, есть флажок, чтобы отслеживать отмеченные <input id="burger" type="checkbox" style="display:none;"/>   -  person    schedule 31.08.2017
comment
@Beth Могу ли я узнать точную проблему с вашим кодом.   -  person Phani Kumar M    schedule 31.08.2017
comment
@PhaniKumarM, когда открывается гамбургер, отображается div, я хочу, чтобы div (.NavMenu) закрывался при нажатии за пределами div или при закрытии гамбургера (X).   -  person    schedule 31.08.2017
comment
@Beth С вашим кодом, когда я нажимаю на красную часть, div NavMenu закрывается. Чтобы закрыть NavMenu с помощью гамбургера (X), нужно дважды щелкнуть. Итак, проблема заключается в закрытии div NavMenu одним щелчком гамбургера (X)?   -  person Phani Kumar M    schedule 31.08.2017
comment
@PhaniKumarM да, именно!   -  person    schedule 31.08.2017


Ответы (2)


Вы можете проверить щелчок по телу, если вы нажмете на любой участок гамбургера и проигнорируете его.

$('#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>

Важно

Но, если вы используете флажок with, я рекомендую вам попробовать сделать это с помощью css, используя только селектор ~.

.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>

person Mosh Feu    schedule 31.08.2017
comment
Большое спасибо, но для меня он также не закрывается при нажатии на красный, так что за пределами div? - person ; 31.08.2017
comment
Извините, я попробовал вторую версию, первая версия работает! но щелчок работает только в определенных частях X, в чем причина этого? - person ; 31.08.2017
comment
@Beth, я пытался удалить span из if ($(e.target).is($('.hamburger-trigger span'))) из первого фрагмента, и это позволит вам щелкнуть всю метку, чтобы закрыть раскрывающийся список, а не определенную часть X. Причина в том, что span повернуты, поэтому их нелегко нажмите на. - person brian17han; 31.08.2017
comment
@Brian17han, это именно то, что мне было нужно! большое место является причиной того, что диапазон меньше, чем гамбургер в css или? в любом случае большое спасибо!!! - person ; 31.08.2017
comment
@ Бет, да, причина в том, что span маленькие и повернуты. - person brian17han; 31.08.2017
comment
@ Brian17han есть небольшая часть гамбургера, которую я только что нашел, которая, кажется, до сих пор не определяет, какая горизонтальная линия находится точно посередине? вы получаете это или знаете, что может вызвать? - person ; 31.08.2017
comment
Конечно, if $('.hamburger-trigger, .hamburger-trigger span') - person Mosh Feu; 31.08.2017
comment
@MoshFeu я использовал || и это не работало, но теперь это идеально, используя (я новичок в javascript), большое спасибо за вашу помощь! - person ; 31.08.2017
comment
Конечно! Поэтому мы здесь :) - person Mosh Feu; 31.08.2017
comment
Спасибо @brian17han очень ценю! - person Mosh Feu; 31.08.2017

Чтобы снова открыть его, просто измените строку:

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

to

$('body').not('#burger').click(function() {
person Sablefoste    schedule 31.08.2017
comment
Спасибо, у меня это не работает, однако, когда меню открывается после первого нажатия на гамбургер, и я снова нажимаю на (X), ничего не происходит? - person ; 31.08.2017
comment
Да, X ничего не делает, потому что в своем вызове $('#burger').click(function(event) { вы ссылаетесь на $(this).is(':checked'), который не работает в исходной скрипке. Вы можете рассмотреть возможность добавления и удаления класса (по щелчку), чтобы эта часть работала. - person Sablefoste; 31.08.2017
comment
спасибо Sablefoste, $(this).is(':checked') вообще не работает в оригинале? Как это сделать, добавив или удалив класс? - person ; 31.08.2017
comment
Она не будет работать. $('body').not('#burger') равно $('body'). not означает, что он удаляет элементы из коллекции, но коллекция $('body') содержит только body, но не #burger. Вы можете увидеть здесь: output.jsbin.com/kedoya и посмотреть файл console. - person Mosh Feu; 31.08.2017