如何关闭sidenav菜单时,单击容器div



我正在构建一个sidenav菜单,当单击按钮时显示和消失。我在这里学到了很多关于栈的知识,用户帮助了我,但是现在我不能集成一个函数。

在代码中可以看到,如果单击按钮菜单,则侧边打开或关闭,如果再次按下。除了正常工作的按钮,我希望能够关闭菜单时,单击div容器外。我试着做一些事情,得到了一半的结果,问题是,现在菜单打开,即使不点击按钮和页面上的所有其他元素显然不起作用。我想这是因为.mts_mob_container需要全宽度,但如果我不这样做,我怎么能通过点击外部div关闭菜单?

我正在做一些明显的错误,但我不知道是什么。我还是个初学者,很抱歉犯了很多错误。有人能帮帮我吗?感谢您的回复,谢谢。

编辑代码工作在这里的堆栈和jsfiddle,除了在我的网站。感谢@user2495207的介入,菜单按我想要的工作!我试着把所有的东西都放在我的网站上(我把它放在标题菜单中),它通过按钮打开和关闭,但是当我点击div外部时,它不会关闭。

正如你在这里看到的,它是有效的。我错过什么了吗?

var menu = document.querySelector(".mob_menu_button");
function mobile_menu() {
var x = document.getElementById("mts_mobile_menu");
if (!x.classList.contains("side_show")) {
x.classList.add ("side_show");
menu.innerHTML = 'Close Menu';

} else { 
x.classList.add("side_hide");
menu.innerHTML = 'Open Menu';
setTimeout(function(){
x.classList.remove("side_show");
x.classList.remove("side_hide");  
},300)
}
}
document.addEventListener("click", function (e) {
var x = document.getElementById("mts_mobile_menu");
if (e.target.localName == "html" && x.classList.contains("side_show")) {
x.classList.add("side_hide");
menu.innerHTML = "<span>Open menu</span>";
setTimeout(function () {
x.classList.remove("side_show");
x.classList.remove("side_hide");
}, 300);
}
});
/*Items menu*/
.user_menu {
display: flex;
flex-direction: column;
}

/*Menu header info*/
.display.name {
font-size: 15px;
font-weight: 500;
color: #303238;
}
.display.mail {
font-size: 13px;
color: #3d5afe;
}
hr.solid {
border-top: 1px solid #e0e0e0;
margin: 10px 0px 10px 0px;
}

/*Text Link css*/
.user_menu.item>a {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 8px 0;
font-size: 13px;
color: #75777D;
}
.user_menu.item:hover>a {
color: #2E323A;
}
/*Icon Button Toggle Menu*/
.mob_menu_button {
display: flex;
align-items: center;
width: 120px;
position: absolute;
top: 10px;
right: 10px;
background: #fbfbfb!important;
font-weight: 500!important;
justify-content: center;
}
.icn_button {
margin: 0;
font-size: 14px;
}
.icn_button:before {
margin: 0;
}
.icn_button:after {
margin: 0;
}

/*Icon Items Menu*/
.icn_menu:before,
.icon_menu:after {
margin: 0px;
padding: 0px;
font-size: 16px
}
.icn_menu {
margin-right: 10px;
display: flex !important;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
}

/* User Menu For header website */
.mts_mob_container {
display:flex;
position:fixed;
z-index: 999;
height: 100%;
top: 0;
left: 0;
}
.mts_sidenav_box {
display: block;
}
.mts_sidenav_content {
display: none;
padding: 20px;
background-color: #fff;
min-width: 160px;
width: 280px;
border-radius: 3px;
overflow-x: hidden;
overflow-y: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 999;
position: relative;
animation: animateFromLeft .3s;
}
@keyframes animateFromLeft {
from {
left: -500px;
opacity: 0;
}
to {
left: 0;
opacity: 1;
}
}
@keyframes animateToLeft {
from {
left: 0;
opacity: 1;
}
to {
left: -500px;
opacity: 0;
}
}
.side_show {
display: block !important;
height: 100vh;
overflow: hidden;
width: 100%;
}
.mts_sidenav_content.side_hide {
animation: animateToLeft .4s;
}
<button onclick="mobile_menu()" class="mob_menu_button">Open Menu</button>
<div class="mts_mob_container">
<div class="mts_sidenav_box">

<div id="mts_mobile_menu" class="mts_sidenav_content">

<div class="user_menu header">
<span class="display name">Ciao [display_name]</span>
<span class="display mail">[display_email]</span>
</div>   

<hr class="solid">  

<div class="user_menu item">
<a href="/account">
<i class="icn_menu fa-regular fa-user"></i>
<span class="link_text">Dashboard</span>
</a>
</div>

<div class="user_menu item">
<a href="ordini">
<i class="icn_menu fa-regular fa-basket-shopping"></i>
<span class="link_text">I miei ordini</span>
</a>
</div>

<div class="user_menu item">
<a href="libreria">
<i class="icn_menu fa-regular fa-cloud-arrow-down"></i>
<span class="link_text">Downloads</span>
</a>
</div>

<div class="user_menu item">
<a href="impostazioni">
<i class="icn_menu fa-regular fa-gear"></i>
<span class="link_text">Impostazioni</span>
</a>
</div>

<div class="user_menu item">
<a href="wp-login.php?action=logout">
<i class="icn_menu fa-regular fa-arrow-right-from-bracket"></i>
<span class="link_text">Logout</span>
</a>
</div>
</div>

</div>
</div>

如果你在浏览器中检查.mts_mob_container元素,你会发现它覆盖了按钮(按钮没有触发任何事件),所以我不得不注释它的尺寸:

.mts_mob_container {
display: flex;
position: fixed;
z-index: 999;
/* height: 100%; */
top: 0;
left: 0;
/* width: 100%;*/
}

我还添加了这个块,当用户单击sidenav外部时的事件,内部的代码与mobile_menu函数的其他部分相同,以关闭sidenav。

document.addEventListener("click", function (e) {
var x = document.getElementById("mts_mobile_menu");
if (e.target.id !== "mts_mobile_menu" && x.classList.contains("side_show")) {
x.classList.add("side_hide");
menu.innerHTML = "<span>Open menu</span>";
var y = document.getElementById("closing_div");
if (!x.classList.contains("side_show")) {
x.classList.add("side_hide");
}
setTimeout(function () {
x.classList.remove("side_show");
x.classList.remove("side_hide");
}, 500);
}
});

更新:
按钮事件正在传播到它的父document,所以我添加了e.stopPropagation();
document;if语句if(e.target.id !== "mts_mobile_menu" && x.classList.contains("side_show"))表示如果所单击的目标不是sidenav并显示

,则执行该语句。

var menu = document.querySelector(".mob_menu_button");
function mobile_menu(e) {
e.stopPropagation();
var x = document.getElementById("mts_mobile_menu");
if (!x.classList.contains("side_show")) {
x.classList.add("side_show");
menu.innerHTML = "<span>Close menu</span>";
} else {
x.classList.add("side_hide");
menu.innerHTML = "<span>Open menu</span>";
var y = document.getElementById("closing_div");
if (!x.classList.contains("side_show")) {
x.classList.add("side_hide");
}
setTimeout(function () {
x.classList.remove("side_show");
x.classList.remove("side_hide");
}, 500);
}
}
document.addEventListener("click", function (e) {
var x = document.getElementById("mts_mobile_menu");
if (e.target.id !== "mts_mobile_menu" && x.classList.contains("side_show")) {
x.classList.add("side_hide");
menu.innerHTML = "<span>Open menu</span>";
var y = document.getElementById("closing_div");
if (!x.classList.contains("side_show")) {
x.classList.add("side_hide");
}
setTimeout(function () {
x.classList.remove("side_show");
x.classList.remove("side_hide");
}, 500);
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/*Items menu*/
.user_menu {
display: flex;
flex-direction: column;
}
/*Menu header info*/
.display.name {
font-size: 15px;
font-weight: 500;
color: #303238;
}
.display.mail {
font-size: 13px;
color: #3d5afe;
}
hr.solid {
border-top: 1px solid #e0e0e0;
margin: 10px 0px 10px 0px;
}
/*Text Link css*/
.user_menu.item > a {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 8px 0;
font-size: 13px;
color: #75777d;
}
.user_menu.item:hover > a {
color: #2e323a;
}
/*Icon Button Toggle Menu*/
.mob_menu_button {
display: flex;
align-content: center;
justify-content: center;
align-items: center;
width: 100px;
position: absolute;
top: 10px;
right: 10px;
background: #fbfbfb !important;
font-weight: 500 !important;
}
.icn_button {
margin: 0;
font-size: 14px;
}
.icn_button:before {
margin: 0;
}
.icn_button:after {
margin: 0;
}
/*Icon Items Menu*/
.icn_menu:before,
.icon_menu:after {
margin: 0px;
padding: 0px;
font-size: 16px;
}
.icn_menu {
margin-right: 10px;
display: flex !important;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
}
/* User Menu For header website */
.mts_mob_container {
display: flex;
position: fixed;
z-index: 999;
/* height: 100%; */
top: 0;
left: 0;
/* width: 100%;*/
}
.mts_sidenav_box {
display: block;
}
.mts_sidenav_content {
display: none;
padding: 20px;
background-color: #fff;
min-width: 160px;
width: 280px;
border-radius: 3px;
overflow-x: hidden;
overflow-y: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 999;
position: relative;
animation: animateFromLeft 0.6s;
}
@keyframes animateFromLeft {
from {
left: -500px;
opacity: 0;
}
to {
left: 0;
opacity: 1;
}
}
@keyframes animateToLeft {
from {
left: 0;
opacity: 1;
}
to {
left: -500px;
opacity: 0;
}
}
.side_show {
display: block !important;
height: 100vh;
overflow: hidden;
width: 100%;
}
.mts_sidenav_content.side_hide {
animation: animateToLeft 0.6s;
}
<button onclick="mobile_menu(event)" class="mob_menu_button">Open menu</button>
<div class="closing_div">
<div class="mts_mob_container">
<div class="mts_sidenav_box">
<div id="mts_mobile_menu" class="mts_sidenav_content">
<div class="user_menu header">
<span class="display name">Ciao [display_name]</span>
<span class="display mail">[display_email]</span>
</div>
<hr class="solid" />
<div class="user_menu item">
<a href="/account">
<i class="icn_menu fa-regular fa-user"></i>
<span class="link_text">Dashboard</span>
</a>
</div>
<div class="user_menu item">
<a href="ordini">
<i class="icn_menu fa-regular fa-basket-shopping"></i>
<span class="link_text">I miei ordini</span>
</a>
</div>
<div class="user_menu item">
<a href="libreria">
<i class="icn_menu fa-regular fa-cloud-arrow-down"></i>
<span class="link_text">Downloads</span>
</a>
</div>
<div class="user_menu item">
<a href="impostazioni">
<i class="icn_menu fa-regular fa-gear"></i>
<span class="link_text">Impostazioni</span>
</a>
</div>
<div class="user_menu item">
<a href="wp-login.php?action=logout">
<i class="icn_menu fa-regular fa-arrow-right-from-bracket"></i>
<span class="link_text">Logout</span>
</a>
</div>
</div>
</div>
</div>
</div>

最新更新