Issue
Edit with solution
I have a sidebar menu that appears and disappears when I click on the button. Two problems were occurring in the menu, here they are listed below:
The menu closes by clicking outside the
#mobile_menu
div and that's what I want. However the menu also closes by clicking inside div#mobile_menu
, I don't want that to happen, clicking inside this div the menu should not close.The second aspect is that when the menu is open, the back page is free to scroll up and down, is there any way to prevent this ?
I solved these problems thanks to the intervention of @moronator
var mobileMenu = document.querySelector("#toggle_menu");
function mobile_menu(e) {
e.stopPropagation();
var x = document.getElementById("mobile_menu");
var y = document.getElementById("container_overlay");
var z = document.getElementsByTagName("body")[0];
// For var x - Show & Hide Menu
if (!x.classList.contains("show")) {
x.classList.toggle("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-xmark">Close Menu</i>';
} else {
x.classList.remove("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-bars">Open Menu</i>';
}
// For var y Show & Hide Overlay
if (!y.classList.contains("on")) {
y.classList.toggle("on");
} else {
y.classList.remove("on");
}
// For var z Prevent Page scroll with overflow
if (!z.classList.contains("ppscroll")) {
z.classList.toggle("ppscroll");
} else {
z.classList.remove("ppscroll");
}
}
// Close Menu clicking on container_overlay
document.getElementById("container_overlay").addEventListener("click", function (e) {
var x = document.getElementById("mobile_menu");
var y = document.getElementById("container_overlay");
var z = document.getElementsByTagName("body")[0];
// For var x
if (e.target.id !== "mobile_menu" && x.classList.contains("show")) {
x.classList.toggle("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-bars">Open Menu</i>';
}
// For var y
if (e.target.id !== "mobile_menu" && y.classList.contains("on")) {
y.classList.toggle("on");
}
// For var z
if (e.target.id !== "mobile_menu" && z.classList.contains("ppscroll")) {
z.classList.toggle("ppscroll");
}
});
/*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;
}
/*Logout Header*/
.logout_header {
display: flex;
justify-content: space-between;
}
.mob {
display: flex;
width: 49.5%;
justify-content: center;
background: #fbfbfb;
border: 1px solid #eee;
border-radius: 4px;
padding: 4px;
}
/*Text Link css*/
.mob_menu.item > a {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 8px 0;
font-size: 13px;
color: #75777d;
}
.mob_menu.item:hover > a {
color: #2e323a;
}
/*Icon Button Toggle Menu*/
#toggle_menu {
width: 20%;
color: #000;
position: absolute;
right: 20px;
top: 20px;
}
.icn_toggle, .icn_toggle::before, .icn_toggle::after {
margin: 0;
z-index: 1000;
font-size: 24px;
}
/*Icon Items Menu*/
.icn_items:before, .icon_menu:after {
margin: 0px;
padding: 0px;
font-size: 16px;
}
.icn_items {
margin-right: 10px;
display: flex !important;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
}
/* User Menu For header website */
#container_overlay {
visibility: hidden;
position: fixed;
z-index: 998;
top: 0;
left: 0;
width: 100%;
background: #000000d6;
opacity: 0;
transition: 0.3s;
height: 100vh;
}
#container_overlay.on {
visibility: visible;
opacity: 1;
}
.content_menu {
display: block;
width: 100%;
}
#mobile_menu {
top: 0;
left: -100%;
padding: 20px;
background-color: #fff;
min-width: 160px;
overflow-x: hidden;
overflow-y: auto;
z-index: 999;
position: fixed;
width: 75%;
height: 100vh;
transition: .3s;
}
#mobile_menu.show {
left: 0;
}
.ppscroll {
overflow: hidden;
}
/* Dropdown Button */
.dropbtn {
background-color: #04AA6D;
color: white;
padding: 16px;
font-size: 16px;
border: none;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {background-color: #ddd;}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {display: block;}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .dropbtn {background-color: #3e8e41;}
<div onclick="mobile_menu(event)" id="toggle_menu"><i class="icn_toggle fa-solid fa-bars">Open Menu</i></div>
<div id="mobile_menu">
<div class="content_menu">
<div class="user_menu header">
<span class="display name">Ciao [display_name]</span>
<span class="display mail">[display_email]</span>
</div>
<div class="logout_header">
<a class="mob btn-login" href="#"><span>Login</span></a>
<a class="mob btn-singup" href="#"> <span>Singup</span></a>
</div>
<hr class="solid" />
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-user"></i>
<span class="link_text">Dashboard</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-basket-shopping"></i>
<span class="link_text">I miei ordini</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-cloud-arrow-down"></i>
<span class="link_text">Downloads</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-gear"></i>
<span class="link_text">Impostazioni</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-arrow-right-from-bracket"></i>
<span class="link_text">Logout</span>
</a>
</div>
</div>
</div>
<div id="container_overlay"></div>
Original code with errors listed
var mobileMenu = document.querySelector("#toggle_menu");
function mobile_menu(e) {
e.stopPropagation();
var x = document.getElementById("mobile_menu");
var y = document.getElementById("container_overlay");
// For var x
if (!x.classList.contains("show")) {
x.classList.toggle("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-xmark">Close Menu</i>';
} else {
x.classList.remove("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-bars">Open Menu</i>';
}
// For var y
if (!y.classList.contains("on")) {
y.classList.toggle("on");
} else {
y.classList.remove("on");
}
}
// Close Menu clicking on container_overlay
document.addEventListener("click", function (e) {
var x = document.getElementById("mobile_menu");
var y = document.getElementById("container_overlay");
// For var x
if (e.target.id !== "mobile_menu" && x.classList.contains("show")) {
x.classList.toggle("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-bars">Open Menu</i>';
}
// For var y
if (e.target.id !== "mobile_menu" && y.classList.contains("on")) {
y.classList.toggle("on");
}
});
/*Items menu*/
.user_menu {
display: flex;
flex-direction: column;
cursor: not-allowed;
pointer-events: none !important;
border: 1px solid red;
}
.error {
color: red;
}
/*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;
}
/*Logout Header*/
.logout_header {
display: flex;
justify-content: space-between;
}
.mob {
display: flex;
width: 49.5%;
justify-content: center;
background: #fbfbfb;
border: 1px solid #eee;
border-radius: 4px;
padding: 4px;
}
/*Text Link css*/
.mob_menu.item > a {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 8px 0;
font-size: 13px;
color: #75777d;
}
.mob_menu.item:hover > a {
color: #2e323a;
}
/*Icon Button Toggle Menu*/
#toggle_menu {
display: flex;
align-content: flex-end;
justify-content: center;
align-items: flex-end;
width: 20%;
color: #000;
position: absolute;
top 20px;
right: 20px;
}
.icn_toggle, .icn_toggle::before, .icn_toggle::after {
margin: 0;
z-index: 1000;
font-size: 24px;
}
/*Icon Items Menu*/
.icn_items:before, .icon_menu:after {
margin: 0px;
padding: 0px;
font-size: 16px;
}
.icn_items {
margin-right: 10px;
display: flex !important;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
}
/* User Menu For header website */
#container_overlay {
visibility: hidden;
position: fixed;
z-index: 998;
top: 0;
left: 0;
width: 100%;
background: #000000b8;
opacity: 0;
transition: 0.3s;
height: 100vh;
}
#container_overlay.on {
visibility: visible;
opacity: 1;
}
.content_menu {
display: block;
width: 100%;
}
#mobile_menu {
top: 0;
left: -100%;
padding: 20px;
background-color: #fff;
min-width: 160px;
overflow-x: hidden;
overflow-y: auto;
z-index: 999;
position: fixed;
width: 75%;
height: 100vh;
transition: .3s;
}
#mobile_menu.show {
left: 0;
}
<div onclick="mobile_menu(event)" id="toggle_menu"><i class="icn_toggle fa-solid fa-bars"></i>Menu</div>
<div id="mobile_menu">
<div class="content_menu">
<div class="user_menu header">
<span class="display name">Hello [display_name]</span>
<span class="display mail">[display_email]</span>
<span class="error">clicking here closes the menu, it shouldn't happen.
</div>
<div class="logout_header">
<a class="mob btn-login" href="#"><span>Login</span></a>
<a class="mob btn-singup" href="#"> <span>Singup</span></a>
</div>
<hr class="solid" />
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-user"></i>
<span class="link_text">Dashboard</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-basket-shopping"></i>
<span class="link_text">I miei ordini</span>
</a>
</div>
<div class="mob_menu item">
<a href="libreria">
<i class="icn_items fa-regular fa-cloud-arrow-down"></i>
<span class="link_text">Downloads</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-gear"></i>
<span class="link_text">Impostazioni</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-arrow-right-from-bracket"></i>
<span class="link_text">Logout</span>
</a>
</div>
</div>
</div>
<div id="container_overlay"></div>
Solution
Just add the event listener to your overlay container instead of your whole document:
var mobileMenu = document.querySelector("#toggle_menu");
function mobile_menu(e) {
e.stopPropagation();
var x = document.getElementById("mobile_menu");
var y = document.getElementById("container_overlay");
// For var x
if (!x.classList.contains("show")) {
x.classList.toggle("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-xmark">Close Menu</i>';
} else {
x.classList.remove("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-bars">Open Menu</i>';
}
// For var y
if (!y.classList.contains("on")) {
y.classList.toggle("on");
} else {
y.classList.remove("on");
}
}
// Close Menu clicking on container_overlay
// ------- I JUST CHANGED THE FOLLOWING LINE -------
document.getElementById("container_overlay").addEventListener("click", function (e) {
var x = document.getElementById("mobile_menu");
var y = document.getElementById("container_overlay");
// For var x
if (e.target.id !== "mobile_menu" && x.classList.contains("show")) {
x.classList.toggle("show");
mobileMenu.innerHTML = '<i class="icn_toggle fa-solid fa-bars">Open Menu</i>';
}
// For var y
if (e.target.id !== "mobile_menu" && y.classList.contains("on")) {
y.classList.toggle("on");
}
});
/*Items menu*/
.user_menu {
display: flex;
flex-direction: column;
cursor: not-allowed;
pointer-events: none !important;
border: 1px solid red;
}
.error {
color: red;
}
/*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;
}
/*Logout Header*/
.logout_header {
display: flex;
justify-content: space-between;
}
.mob {
display: flex;
width: 49.5%;
justify-content: center;
background: #fbfbfb;
border: 1px solid #eee;
border-radius: 4px;
padding: 4px;
}
/*Text Link css*/
.mob_menu.item > a {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 8px 0;
font-size: 13px;
color: #75777d;
}
.mob_menu.item:hover > a {
color: #2e323a;
}
/*Icon Button Toggle Menu*/
#toggle_menu {
display: flex;
align-content: flex-end;
justify-content: center;
align-items: flex-end;
width: 20%;
color: #000;
position: absolute;
top 20px;
right: 20px;
}
.icn_toggle, .icn_toggle::before, .icn_toggle::after {
margin: 0;
z-index: 1000;
font-size: 24px;
}
/*Icon Items Menu*/
.icn_items:before, .icon_menu:after {
margin: 0px;
padding: 0px;
font-size: 16px;
}
.icn_items {
margin-right: 10px;
display: flex !important;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
}
/* User Menu For header website */
#container_overlay {
visibility: hidden;
position: fixed;
z-index: 998;
top: 0;
left: 0;
width: 100%;
background: #000000b8;
opacity: 0;
transition: 0.3s;
height: 100vh;
}
#container_overlay.on {
visibility: visible;
opacity: 1;
}
.content_menu {
display: block;
width: 100%;
}
#mobile_menu {
top: 0;
left: -100%;
padding: 20px;
background-color: #fff;
min-width: 160px;
overflow-x: hidden;
overflow-y: auto;
z-index: 999;
position: fixed;
width: 75%;
height: 100vh;
transition: .3s;
}
#mobile_menu.show {
left: 0;
}
<div onclick="mobile_menu(event)" id="toggle_menu"><i class="icn_toggle fa-solid fa-bars"></i>Menu</div>
<div id="mobile_menu">
<div class="content_menu">
<div class="user_menu header">
<span class="display name">Hello [display_name]</span>
<span class="display mail">[display_email]</span>
<span class="error">clicking here closes the menu, it shouldn't happen.
</div>
<div class="logout_header">
<a class="mob btn-login" href="#"><span>Login</span></a>
<a class="mob btn-singup" href="#"> <span>Singup</span></a>
</div>
<hr class="solid" />
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-user"></i>
<span class="link_text">Dashboard</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-basket-shopping"></i>
<span class="link_text">I miei ordini</span>
</a>
</div>
<div class="mob_menu item">
<a href="libreria">
<i class="icn_items fa-regular fa-cloud-arrow-down"></i>
<span class="link_text">Downloads</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-gear"></i>
<span class="link_text">Impostazioni</span>
</a>
</div>
<div class="mob_menu item">
<a href="#">
<i class="icn_items fa-regular fa-arrow-right-from-bracket"></i>
<span class="link_text">Logout</span>
</a>
</div>
</div>
</div>
<div id="container_overlay"></div>
Answered By - moronator Answer Checked By - David Goodson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.