在菜单外单击以关闭菜单
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);"
是过去的事情。
我创建了一个移动菜单,点击汉堡包按钮即可打开。目前我只能通过点击汉堡包按钮来关闭菜单。我需要添加什么才能通过单击页面上的其他位置来关闭菜单?
下面的代码。
抱歉这个基本问题!在此先感谢您的帮助。
约旦
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);"
是过去的事情。