Закрыть меню, щелкнув снаружи - PullRequest
0 голосов
/ 22 марта 2019

Я создал мобильное меню, которое открывается при нажатии на кнопку гамбургера.В настоящее время я могу только закрыть меню, нажав кнопку гамбургера.Что мне нужно добавить, чтобы можно было закрыть меню, нажав в другом месте на странице?

Код ниже.

Извинения за основной вопрос!Заранее благодарим за любую помощь.

Иордания

   function myFunction() {
      var x = document.getElementById("myLinks");
      if (x.style.display === "block") {
        x.style.display = "none";
      } else {
        x.style.display = "block";
      }
    }
<div class="topnav">
    <a href="#home" class="nt"><strong>NELSON TRAILS</strong></a>
    <div id="myLinks">
    <a class="sub">SHORT WALKS</a>
    <a class="sub">DAY TRIPS</a>
    <a class="sub">MULTI-DAY</a>
    <a class="sub">MAP EXPLORER</a> 
    <a class="sub">TRAIL SEARCH AND FILTER</a>
    <a class="sub">TRAIL ALERTS</a>
    <a class="sub">ABOUT</a>
 </div>
 <a href="javascript:void(0);" class="icon" onclick="myFunction()"><i class="fa fa-bars"></i></a>
</div>

Ответы [ 3 ]

1 голос
/ 22 марта 2019

Как и в предыдущем ответе, есть много способов решить эту проблему. Альтернативный способ - использовать события focus и blur . Как говорилось в предыдущем комментарии, вы можете избежать загрязнения глобального пространства имен.

Вот реализация, использующая события фокуса и размытия.

function onClick(e) {
  if (myLinks.classList.contains('hidden')) {
    myLinks.classList.remove('hidden');
    navMenu.focus();
  } else {
    myLinks.classList.add('hidden');
    navMenu.blur()
  }
}

function onBlur() {
  myLinks.classList.add('hidden');
}

var myLinks = document.getElementById("myLinks");
var navMenu = document.querySelector('.topnav')
var myBtn = document.getElementById('home');
myBtn.addEventListener('click', onClick);
navMenu.addEventListener('blur', onBlur);
.topnav {
  border: 1px dashed blue;
}

.sub {
  display: block;
}

.hidden {
  display: none;
}
<div class="topnav" tabindex="0">
  <a id="home" class="nt"><strong>NELSON TRAILS</strong></a>
  <div id="myLinks" class="hidden">
    <a class="sub">SHORT WALKS</a>
    <a class="sub">DAY TRIPS</a>
    <a class="sub">MULTI-DAY</a>
    <a class="sub">MAP EXPLORER</a>
    <a class="sub">TRAIL SEARCH AND FILTER</a>
    <a class="sub">TRAIL ALERTS</a>
    <a class="sub">ABOUT</a>
  </div>
</div>
1 голос
/ 22 марта 2019

Есть много способов, один, если использовать общее событие onclick в вышестоящем элементе. Вот пример:

function myFunction() {
      var x = document.getElementById("myLinks");
      if (x.style.display === "block") {
        x.style.display = "none";
      } else {
        x.style.display = "block";
      }
    }
    
window.onclick = myFunction;
<div class="topnav">
    <a href="#home" class="nt"><strong>NELSON TRAILS</strong></a>
    <div id="myLinks">
    <a class="sub">SHORT WALKS</a>
    <a class="sub">DAY TRIPS</a>
    <a class="sub">MULTI-DAY</a>
    <a class="sub">MAP EXPLORER</a> 
    <a class="sub">TRAIL SEARCH AND FILTER</a>
    <a class="sub">TRAIL ALERTS</a>
    <a class="sub">ABOUT</a>
 </div>
 <a class="icon" onclick="myFunction()"><i class="fa fa-bars">Menu</i></a>
</div>

Конечно, window не очень хороший элемент для использования, потому что он создает пространство имен js. Поместите это в элемент, который находится над вашим меню и охватывает всю страницу. Вы можете использовать корневой div или что-то в этом роде.

0 голосов
/ 22 марта 2019

Этот метод, вероятно, не самый лучший (один с размытием / фокусом лучше imo), но есть много разных способов сделать это, так что здесь идет другой.

function openModal(){
	var x = document.getElementById('myLinks');
	if(x.style.display != 'block'){
		x.style.display = 'block';
		window.addEventListener('click', closeMenu, {capture: true});
	}
}

function closeMenu(event){
	var el = document.getElementById('myLinks');
	if(el.style.display == 'block' && event.target != el){
		window.removeEventListener('click', closeMenu, {capture: true});
		el.style.display = 'none';
	}
}
div#myLinks{
	display: none;
}
<div class="topnav">
    <a href="#home" class="nt"><strong>NELSON TRAILS</strong></a>
    <div id="myLinks">
    <a class="sub">SHORT WALKS</a>
    <a class="sub">DAY TRIPS</a>
    <a class="sub">MULTI-DAY</a>
    <a class="sub">MAP EXPLORER</a> 
    <a class="sub">TRAIL SEARCH AND FILTER</a>
    <a class="sub">TRAIL ALERTS</a>
    <a class="sub">ABOUT</a>
 </div>
 <p class="icon" onclick="openModal()">Menu</p>
</div>

Нам нужна опция capture для прослушивателя событий, чтобы она не срабатывала после первого щелчка. Этот метод намного меньше загрязняет window, потому что наш слушатель существует только при открытом меню.

Также не следует использовать javascript:void(0) для предотвращения перенаправления. Что вы должны сделать, это что-то вроде этого:

document.addEventListener('DOMContentLoaded', function(){
	document.querySelectorAll('a.prevent-default').forEach(function(el, i){
		el.addEventListener('click', preventDefault);
	});
});

function preventDefault(event){
	event.preventDefault();
}
<a href="google.com" class="my-class prevent-default">Can't go through me!</a>

Это найдет все элементы a с классом prevent-default и предотвратит перенаправление. Использование href="javascript:void(0);" - это то, что осталось в прошлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...