I have a dropdown menu that works fine. The button allows me to open and close the menu, however, if I click on the body page the menu does not close, only clicking on the button can close it.
So I would like it to close even if I click on the body of the page or anything else that isn't the button. I'm trying to close the menu with document.body.addEventListener but it doesn't work, I don't understand what I'm doing wrong. Can someone help me by pointing me the right way?
I appreciate any response, thanks.
var usermenu = document.querySelector(".user_menu_button");
function userMenu() {
var x = document.getElementById("mts_menu");
if (x.classList.toggle ("show")) {
usermenu.innerHTML = '<i ></i><span >Account</span>';
} else {
usermenu.innerHTML = '<i ></i><span >Account</span>';
}
}
// Close Menu clicking on body or Anywhere
document.body.addEventListener("click", function() {
var x = document.getElementById("mts_menu");
// For var x
if (e.target.id !== "mts_menu" && x.classList.contains("show")) {
x.classList.toggle("show");
}
});
/*Button Toggle Menu*/
.user_menu_button {
display: flex;
align-content: center;
justify-content: center;
align-items: center;
width: 100%;
height: 32px;
background: #3D4350!important;
border-radius: 4px;
padding: 12px;
font-size: 14px!important;
line-height: 2;
}
.icn_button {
margin: 0;
}
.icn_button:before, .icn_button:after {
margin: 0;
}
.txt_button {
margin-left: 10px;
color: #fff;
font-size: 14px;
font-weight: 400;
}
/*Items menu*/
.user_menu {
display: flex;
flex-direction: column;
}
.user_menu.header {
padding: 15px 15px;
}
/*Menu header info*/
.display.name {
font-size: 14px;
font-weight: 500;
color: #303238;
line-height: 1.5;
}
.display.mail {
font-size: 13px;
color: #1E70EB;
line-height: 1.5;
}
hr.divider-menu {
border-top: 1px solid #e0e0e0;
}
/*Text Link css*/
.mnu_margin {
margin: 7px 0;
}
.user_menu.item > a {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 8px 15px;
color: #212629;
}
.user_menu.item:hover > a {
color: #fff;
background: #1E70EB;
transition: all 0.2s;
}
.user_menu.item > a .link_text {
font-size: 14px;
color: #212629;
}
.user_menu.item:hover > a .link_text {
color: #fff;
}
/*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_menu_container {
display: flex;
flex-direction: column;
align-content: flex-end;
align-items: flex-end;
}
.dropdown_box {
position: absolute;
margin-top: 20px;
}
.mts_dropdown_content {
background-color: #fff;
min-width: 160px;
width: 240px;
border-radius: 6px;
overflow-x: hidden;
overflow-y: hidden;
box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px 0px;
z-index: 999;
position: relative;
visibility: hidden;
opacity: 0;
top: 50px;
height: 0;
transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}
.mts_dropdown_content.show {
height: 100%;
visibility: visible;
opacity: 1;
top: 0;
transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}
<button onclick="userMenu()" >
<i ></i>
<span >Account</span>
</button>
<div >
<div >
<div id="mts_menu" >
<div >
<span >Ciao [display_name]</span>
<span >[display_email]</span>
</div>
<hr >
<div >
<div >
<a href="/account">
<i ></i>
<span >Dashboard</span>
</a>
</div>
<div >
<a href="ordini">
<i ></i>
<span >I miei ordini</span>
</a>
</div>
<div >
<a href="libreria">
<i ></i>
<span >Downloads</span>
</a>
</div>
<div >
<a href="impostazioni">
<i ></i>
<span >Impostazioni</span>
</a>
</div>
<div >
<a href="wp-login.php?action=logout">
<i ></i>
<span >Logout</span>
</a>
</div>
</div>
</div>
</div>
</div>
CodePudding user response:
Listen for a click event on the document
object. Inside the handler, check if the clicked element is inside the navigation or not with Element.closest()
.
const usermenu = document.querySelector(".user_menu_button")
const menu = document.querySelector('#mts_menu');
document.addEventListener('click', event => {
const isClickedOutsideMenu = event.target.closest('#mts_menu') === null;
if (isClickedOutsideMenu && menu.classList.contains('open')) {
menu.classList.remove('open');
usermenu.innerHTML = '<i ></i><span >Account</span>';
}
});
CodePudding user response:
I solved it in this way, thanks also to the help of @Emiel
I added event.stopPropagation();
and then
//Closing Menu Part
const closing = document.querySelector("#mts_menu");
document.addEventListener("click", (evt) => {
if (!evt.target.closest("#mts_menu")) closing.classList.remove("show");
});
var usermenu = document.querySelector(".user_menu_button");
function userMenu() {
event.stopPropagation(); //For Closing menu
var x = document.getElementById("mts_menu");
if (x.classList.toggle ("show")) {
usermenu.innerHTML = '<i ></i><span >Account</span>';
} else {
usermenu.innerHTML = '<i ></i><span >Account</span>';
}
}
//Closing Menu Part
const closing = document.querySelector("#mts_menu");
document.addEventListener("click", (evt) => {
if (!evt.target.closest("#mts_menu")) closing.classList.remove("show");
});
/*Button Toggle Menu*/
.user_menu_button {
display: flex;
align-content: center;
justify-content: center;
align-items: center;
width: 100%;
height: 32px;
background: #3D4350!important;
border-radius: 4px;
padding: 12px;
font-size: 14px!important;
line-height: 2;
}
.icn_button {
margin: 0;
}
.icn_button:before, .icn_button:after {
margin: 0;
}
.txt_button {
margin-left: 10px;
color: #fff;
font-size: 14px;
font-weight: 400;
}
/*Items menu*/
.user_menu {
display: flex;
flex-direction: column;
}
.user_menu.header {
padding: 15px 15px;
}
/*Menu header info*/
.display.name {
font-size: 14px;
font-weight: 500;
color: #303238;
line-height: 1.5;
}
.display.mail {
font-size: 13px;
color: #1E70EB;
line-height: 1.5;
}
hr.divider-menu {
border-top: 1px solid #e0e0e0;
}
/*Text Link css*/
.mnu_margin {
margin: 7px 0;
}
.user_menu.item > a {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 8px 15px;
color: #212629;
}
.user_menu.item:hover > a {
color: #fff;
background: #1E70EB;
transition: all 0.2s;
}
.user_menu.item > a .link_text {
font-size: 14px;
color: #212629;
}
.user_menu.item:hover > a .link_text {
color: #fff;
}
/*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_menu_container {
display: flex;
flex-direction: column;
align-content: flex-end;
align-items: flex-end;
}
.dropdown_box {
position: absolute;
margin-top: 20px;
}
.mts_dropdown_content {
background-color: #fff;
min-width: 160px;
width: 240px;
border-radius: 6px;
overflow-x: hidden;
overflow-y: hidden;
box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px 0px;
z-index: 999;
position: relative;
visibility: hidden;
opacity: 0;
top: 50px;
height: 0;
transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}
.mts_dropdown_content.show {
height: 100%;
visibility: visible;
opacity: 1;
top: 0;
transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}
<button onclick="userMenu()" >
<i ></i>
<span >Account</span>
</button>
<div >
<div >
<div id="mts_menu" >
<div >
<span >Ciao [display_name]</span>
<span >[display_email]</span>
</div>
<hr >
<div >
<div >
<a href="/account">
<i ></i>
<span >Dashboard</span>
</a>
</div>
<div >
<a href="ordini">
<i ></i>
<span >I miei ordini</span>
</a>
</div>
<div >
<a href="libreria">
<i ></i>
<span >Downloads</span>
</a>
</div>
<div >
<a href="impostazioni">
<i ></i>
<span >Impostazioni</span>
</a>
</div>
<div >
<a href="wp-login.php?action=logout">
<i ></i>
<span >Logout</span>
</a>
</div>
</div>
</div>
</div>
</div>