通过单击外部关闭菜单

时间:2019-03-21 22:30:25

标签: javascript html menu onclick

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

下面的代码。

道歉的基本问题!预先感谢您的帮助。

乔丹

   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 个答案:

答案 0 :(得分:1)

有很多方法,一种方法是在上级元素中使用通用的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名称空间。将其放在菜单上方的元素中,该元素覆盖整个页面。 您可以使用root div或类似的东西。

答案 1 :(得分:0)

就像前面的回答所说的那样,有很多方法可以解决这个问题。另一种方法是利用focusblur事件。正如前面的评论所说,您可能要避免污染全局名称空间。

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

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>

答案 2 :(得分:0)

此方法可能不是最好的方法(使用模糊/聚焦的方法更适合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);"