在菜单外单击以关闭菜单

Close menu by clicking outside it

我创建了一个移动菜单,点击汉堡包按钮即可打开。目前我只能通过点击汉堡包按钮来关闭菜单。我需要添加什么才能通过单击页面上的其他位置来关闭菜单?

下面的代码。

抱歉这个基本问题!在此先感谢您的帮助。

约旦

   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>

方法有很多种,一种是在高级元素中使用通用的 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 或类似的东西。

正如前面的回答所说,有很多方法可以解决这个问题。另一种方法是利用 focus and blur 事件。正如前面的评论所说,您可能希望避免污染全局名称 space。

这是一个利用焦点和模糊事件的实现。

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>

这个方法可能不是最好的(在我看来 blur/focus 的方法更好)但是有很多不同的方法可以做到这一点所以这里有另一个方法。

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 具有 class prevent-default 的元素并阻止重定向。使用href="javascript:void(0);"是过去的事情。