How to add overlay to sidenav menu? - javascript

I have a sidenav menu with some Js, I would like to add the overlay but I don't know how to do it, sorry but I'm a beginner. I tried several ways without success, even with a div that closes all content, but then I took it out because it broke the menu function. Can someone help me ? I appreciate any response, thanks.
const toggle = document.getElementById('toggle');
const sidenav = document.getElementById('sidenav');
document.onclick = function(e){
if(e.target.id !== 'sidenav' && e.target.id !== 'toggle' ) {
toggle.classList.remove('active');
sidenav.classList.remove('active');
}
}
toggle.onclick = function(){
toggle.classList.toggle('active');
sidenav.classList.toggle('active');
}
#toggle {
display: flex;
align-content: center;
justify-content: flex-end;
align-items: center;
font-size: 18px;
margin: 10px;
padding: 10px;
color: black;
border: 1px solid black;
}
#toggle::before {
font-family: fontAwesome;
content:'Menu Closed';
color: black;
}
#toggle.active::before {
font-family: fontAwesome;
content:'Menu Open';
color: black;
}
/*Sidebar*/
.sidenav_box {
margin-top: 10%;
padding: 25px;
}
#sidenav {
position: fixed;
top: 0;
left:-100%;
width: 80%;
height: 100vh;
background: black;
transition: 0.3s;
z-index: 999;
}
#sidenav.active {
left: 0px;
width: 80%;
}
<div id="toggle"></div>
<div id="sidenav">
<div class="sidenav_box">
<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>

When you say div with overlay, do you mean having the background of your nav menu be semi-transparent like so? If so you just need the opacity attribute but you might need to drop the z-index down if you want it to appear behind your other elements like the nav items.
const toggle = document.getElementById('toggle');
const sidenav = document.getElementById('sidenav');
const overlay = document.getElementById('contentOverlay');
document.onclick = function(e) {
if (e.target.id !== 'sidenav' && e.target.id !== 'toggle') {
toggle.classList.remove('active');
sidenav.classList.remove('active');
overlay.classList.remove('active');
}
}
toggle.onclick = function() {
toggle.classList.toggle('active');
sidenav.classList.toggle('active');
overlay.classList.toggle('active');
}
#toggle {
display: flex;
align-content: center;
justify-content: flex-end;
align-items: center;
font-size: 18px;
margin: 10px;
padding: 10px;
color: black;
border: 1px solid black;
}
#toggle::before {
font-family: fontAwesome;
content: 'Menu Closed';
color: black;
}
#toggle.active::before {
font-family: fontAwesome;
content: 'Menu Open';
color: black;
}
/*Sidebar*/
.sidenav_box {
margin-top: 10%;
padding: 25px;
}
#sidenav {
position: fixed;
top: 0;
left: -100%;
width: 50%;
height: 100vh;
background: black;
opacity: 1;
transition: 0.3s;
z-index: 999;
}
#sidenav.active {
left: 0px;
width: 50%;
}
#contentOverlay {
position: fixed;
top: 0;
left: -100%;
width: 100%;
height: 100vh;
opacity: 1;
object-fit: cover;
transition: 0.3s;
z-index: 1;
}
#contentOverlay.active {
left: 0px;
width: 100%;
}
<div id="toggle"></div>
<div id="sidenav">
<div class="sidenav_box">
<div class="user_menu header">
<span class="display name">Ciao [display_name]</span>
<span class="display mail">[display_email]</span>
</div>
</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>
<img src="https://i.imgur.com/rsSBOSd.jpeg" id="contentOverlay" />

the way i add overlay is i wrap all the content within another div and use a ::after , then i color the after element, then i apply a z-index for the content inside to show up on top, something like this -
header .nav-div {
z-index: 1004;
margin-left: 0;
height: 100vh;
width: 100vw;
position: fixed;
top: 0;
left: 0;
clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
transition: clip-path 0.3s linear;
}
header .nav-div::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
opacity: 0.75;
}
header .nav-div.active {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}
header .nav-div .close {
display: inline-block;
height: 2rem;
position: absolute;
top: 2rem;
right: 2rem;
cursor: pointer;
}
header .nav-div .nav-div-mobile {
z-index: 1005;
background-color: white;
height: 100%;
width: 70%;
}
here .nav-div::after is working as my overlay.
If, I put a opacity on .nav-div this will reduce opacity on all my content inside it. Hence, I put the opacity on the ::after which covers the entire .nav-div, and my main nav tag is inside my .nav-div-mobile(for extra styling purpose).
Putting the .nav-div-mobile on top of the .nav-div is important otherwise it will be behind the colored ::after element

Related

The background menu overlay doesn't make me click anything on the main page

I have a side menu that basically works fine, however the background overlay doesn't allow me to click anything on the website. I'm trying to modify the #container_overlay and #container_overlay.on class. Respectively on the first class I always put a parameter that hides the element, while on the second class (on) put a parameter that shows the element. I have been playing with z-inde -999 to 999 so far and it works, only I get an unpleasant effect during the transition. Then I also tried with left 0 to 100% trying to make a slide of the overlay, and even here I didn't like the effect of the transition.
What I'm trying to do is make the overlay appear only with opacity 0 to 1. But when this is off it stays there to cover everything by not letting me click anything. Is there any way to fix?
Sorry but I'm new, I appreciate any response. Thanks.
var menu = 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("active")) {
x.classList.toggle("active");
menu.innerHTML = '<i class="icn_toggle fa-solid fa-xmark">Close Menu</i>';
} else {
x.classList.remove("active");
menu.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");
}
}
// Permette la chiusura del menu cliccando fuori dall'area
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("active")) {
x.classList.toggle("active");
menu.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");
}
});
.example_content {
display: flex;
align-content: center;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.example_content > a {
background: gray;
padding: 10px;
color:#fff;
}
/*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;
}
.btn {
display: flex;
width: 49.5%;
justify-content: center;
background: #fbfbfb;
border: 1px solid #eee;
border-radius: 4px;
padding: 4px;
}
/*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*/
.toggle_menu {
display: flex;
align-content: center;
justify-content: center;
align-items: center;
width: 20%;
background: none!important;
box-shadow: none!important;
position: absolute;
top: 20px;
right: 20px;
}
.icn_toggle {
margin: 0;
font-size: 26px;
z-index: 1000;
}
/*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 */
#container_overlay {
position: fixed;
z-index: 999;
top: 0;
left: 0;
width: 100%;
background: #000000d6;
opacity: 0;
transition: 0.3s;
}
#container_overlay.on {
opacity: 1;
}
.content_menu {
display: block;
width: 100%;
}
#mobile_menu {
left: -100%;
padding: 20px;
background-color: #fff;
min-width: 160px;
overflow-x: hidden;
overflow-y: auto;
z-index: 999;
position: relative;
width: 75%;
height: 100vh;
transition: .3s;
}
#mobile_menu.active {
left: 0;
}
<div class="example_content">
This is an example of my website content
Stackoverflow Link
</div>
<button onclick="mobile_menu(event)" class="toggle_menu"><i class="icn_toggle fa-solid fa-bars">Open Menu</i></button>
<div id="container_overlay">
<div id="mobile_menu">
<div class="content_menu">
{% if function( 'is_user_logged_in') %}
<div class="user_menu header">
<span class="display name">Ciao [display_name]</span>
<span class="display mail">[display_email]</span>
</div>
{% else %}{% endif %}
<div class="logout_header">
<div class="btn login">Login</div>
<div class="btn singup">Singup</div>
</div>
<hr class="solid" />
{% if function( 'is_user_logged_in') %}
<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>
{% endif %}
</div>
</div>
</div>
give z-index:-1 to #container_overlay and z-index:999 to #container_overlay.on. hope this helps
I found a solution by looking around on stackoverflow. I found this post: Transitions on the CSS display property some users recommend using the visibility parameter: hidden to visible. It worked for me. Below I put the correct code that I am using.
var menu = 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("active")) {
x.classList.toggle("active");
menu.innerHTML = '<i class="icn_toggle fa-solid fa-xmark">Close Menu</i>';
} else {
x.classList.remove("active");
menu.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");
}
}
// Permette la chiusura del menu cliccando fuori dall'area
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("active")) {
x.classList.toggle("active");
menu.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");
}
});
.example_content {
display: flex;
align-content: center;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.example_content > a {
background: gray;
padding: 10px;
color:#fff;
}
/*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;
}
.btn {
display: flex;
width: 49.5%;
justify-content: center;
background: #fbfbfb;
border: 1px solid #eee;
border-radius: 4px;
padding: 4px;
}
/*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*/
.toggle_menu {
display: flex;
align-content: center;
justify-content: center;
align-items: center;
width: 20%;
background: none!important;
box-shadow: none!important;
position: absolute;
top: 20px;
right: 20px;
}
.icn_toggle {
margin: 0;
font-size: 26px;
z-index: 1000;
}
/*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 */
#container_overlay {
visibility: hidden; /*Add This*/
position: fixed;
z-index: 999;
top: 0;
left: 0;
width: 100%;
background: #000000d6;
opacity: 0;
transition: 0.3s;
}
#container_overlay.on {
visibility: visible; /*and this*/
opacity: 1;
}
.content_menu {
display: block;
width: 100%;
}
#mobile_menu {
left: -100%;
padding: 20px;
background-color: #fff;
min-width: 160px;
overflow-x: hidden;
overflow-y: auto;
z-index: 999;
position: relative;
width: 75%;
height: 100vh;
transition: .3s;
}
#mobile_menu.active {
left: 0;
}
<div class="example_content">
This is an example of my website content
Stackoverflow Link
</div>
<button onclick="mobile_menu(event)" class="toggle_menu"><i class="icn_toggle fa-solid fa-bars">Open Menu</i></button>
<div id="container_overlay">
<div id="mobile_menu">
<div class="content_menu">
{% if function( 'is_user_logged_in') %}
<div class="user_menu header">
<span class="display name">Ciao [display_name]</span>
<span class="display mail">[display_email]</span>
</div>
{% else %}{% endif %}
<div class="logout_header">
<div class="btn login">Login</div>
<div class="btn singup">Singup</div>
</div>
<hr class="solid" />
{% if function( 'is_user_logged_in') %}
<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>
{% endif %}
</div>
</div>
</div>

How to prevent page scroll and closing menu when click outside menu container

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>
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>

How can I change tag div to tag button to activate menu with js function?

I have a side menu that appears when I click on a div tag. Everything works fine. However I would like to change <div id="togglek"></div> to <button id="togglek" onclick"MyFunction()"></button> I tried, but with the button tag the menu doesn't appear.
Is there any way to change from div to button? I'm sure the script will need to be changed a bit, but I don't know how. Sorry, I'm new and trying to learn as much as possible.
I appreciate any response, thanks.
const togglek = document.getElementById('togglek');
const sidenav = document.getElementById('sidenav');
document.onclick = function(e){
if(e.target.id !== 'sidenav' && e.target.id !== 'togglek' ) {
togglek.classList.remove('btnactv');
sidenav.classList.remove('active');
overlay.classList.remove('bgover');
}
}
togglek.onclick = function(){
togglek.classList.toggle('btnactv');
sidenav.classList.toggle('active');
overlay.classList.toggle('bgover');
}
/*Overlay*/
#overlay {
position: fixed;
height: 100vh;
top: 0;
background: #000;
z-index: 999;
transition: 0.3s;
}
#overlay.bgover {
left: 0px;
width: 100%;
background: #000000d1;
}
/*Toggle Button*/
#togglek {
display: flex;
align-content: center;
justify-content: center;
align-items: flex-end;
font-size: 18px;
margin: 10px;
padding: 10px;
position: absolute;
top: 10px;
right: 20px;
border: 1px solid black;
}
#togglek::before {
font-family: fontAwesome;
content:'Open';
color: #000;
}
#togglek.btnactv::before {
font-family: fontAwesome;
content:'Close';
color: #000;
z-index:1000;
}
/*Sidebar*/
.sidenav_box {
margin-top: 5%;
padding: 25px;
}
#sidenav {
position: fixed;
top: 0;
left:-100%;
width: 80%;
height: 100vh;
background: #fbfbfb;
transition: 0.3s;
z-index: 1000;
}
#sidenav.active {
left: 0px;
width: 80%;
background: #fbfbfb;
box-shadow: 5px 0px 15px 0px #00000021;
}
/*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;
}
<div id="togglek"></div>
<div id="sidenav">
<div class="sidenav_box">
<div class="user_menu header">
<span class="display name">Hello User</span>
<span class="display mail">example#gmail.com</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 id="overlay"></div>
is this what u mean?
const togglek = document.getElementById('togglek');
const sidenav = document.getElementById('sidenav');
document.onclick = function(e){
if(e.target.id !== 'sidenav' && e.target.id !== 'togglek' ) {
togglek.classList.remove('btnactv');
sidenav.classList.remove('active');
overlay.classList.remove('bgover');
}
}
function pressToShow() {
togglek.classList.toggle('btnactv');
sidenav.classList.toggle('active');
overlay.classList.toggle('bgover');
}
/*Overlay*/
#overlay {
position: fixed;
height: 100vh;
top: 0;
background: #000;
z-index: 999;
transition: 0.3s;
}
#overlay.bgover {
left: 0px;
width: 100%;
background: #000000d1;
}
/*Toggle Button*/
#togglek {
display: flex;
align-content: center;
justify-content: center;
align-items: flex-end;
font-size: 18px;
margin: 10px;
padding: 10px;
position: absolute;
top: 10px;
right: 20px;
border: 1px solid black;
}
/*Sidebar*/
.sidenav_box {
margin-top: 5%;
padding: 25px;
}
#sidenav {
position: fixed;
top: 0;
left:-100%;
width: 80%;
height: 100vh;
background: #fbfbfb;
transition: 0.3s;
z-index: 1000;
}
#sidenav.active {
left: 0px;
width: 80%;
background: #fbfbfb;
box-shadow: 5px 0px 15px 0px #00000021;
}
/*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;
}
<button id="togglek" onclick=pressToShow()>PRESS TO SHOW</div>
<div id="sidenav">
<div class="sidenav_box">
<div class="user_menu header">
<span class="display name">Hello User</span>
<span class="display mail">example#gmail.com</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 id="overlay"></div>
It seems your issue is that you aren't defining a function of myFunction you can simply change the div to a button and use the existing onclick code and it still works as shown:
const togglek = document.getElementById('togglek');
const sidenav = document.getElementById('sidenav');
document.onclick = function(e){
if(e.target.id !== 'sidenav' && e.target.id !== 'togglek' ) {
togglek.classList.remove('btnactv');
sidenav.classList.remove('active');
overlay.classList.remove('bgover');
}
}
togglek.onclick = function(){
togglek.classList.toggle('btnactv');
sidenav.classList.toggle('active');
overlay.classList.toggle('bgover');
}
/*Overlay*/
#overlay {
position: fixed;
height: 100vh;
top: 0;
background: #000;
z-index: 999;
transition: 0.3s;
}
#overlay.bgover {
left: 0px;
width: 100%;
background: #000000d1;
}
/*Toggle Button*/
#togglek {
display: flex;
align-content: center;
justify-content: center;
align-items: flex-end;
font-size: 18px;
margin: 10px;
padding: 10px;
position: absolute;
top: 10px;
right: 20px;
border: 1px solid black;
}
#togglek::before {
font-family: fontAwesome;
content:'Open';
color: #000;
}
#togglek.btnactv::before {
font-family: fontAwesome;
content:'Close';
color: #000;
z-index:1000;
}
/*Sidebar*/
.sidenav_box {
margin-top: 5%;
padding: 25px;
}
#sidenav {
position: fixed;
top: 0;
left:-100%;
width: 80%;
height: 100vh;
background: #fbfbfb;
transition: 0.3s;
z-index: 1000;
}
#sidenav.active {
left: 0px;
width: 80%;
background: #fbfbfb;
box-shadow: 5px 0px 15px 0px #00000021;
}
/*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;
}
<button id="togglek"/>
<div id="sidenav">
<div class="sidenav_box">
<div class="user_menu header">
<span class="display name">Hello User</span>
<span class="display mail">example#gmail.com</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 id="overlay"></div>
Seems to be working for me. Here's the jsfiddle
In the html I just changed
<div id="togglek"></div>
to
<button id="togglek" onclick="MyFunction()"></button>
And in the js:
togglek.onclick = function(){
togglek.classList.toggle('btnactv');
sidenav.classList.toggle('active');
overlay.classList.toggle('bgover');
}
to
function MyFunction() {
togglek.classList.toggle('btnactv');
sidenav.classList.toggle('active');
overlay.classList.toggle('bgover');
}

How to close sidenav menu when click out of container div

I'm building a sidenav menu that appears and disappears when click a button. I learned a lot here about stacks, users have helped me up to this point, but now I can't integrate a function.
As you can see in the code, if you click button menu, the sidenav opens or closes if you press again. In addition to the button that works correctly, I would like to be able to close the menu when clicking outside the div container. I tried to do something and got half result, the problem is that now the menu opens even when don't click on the button and all the other elements on the page obviously don't work. I suppose this happens because the .mts_mob_container takes full width, but if I don't do so how can I close the menu by clicking outside the div?
I'm doing something obvious wrong, but I can't figure out what. I'm still a beginner, sorry for the many mistakes. Can someone help me ? I appreciate any response, thanks.
Edit: The code works here on stack and jsfiddle, except on my website.
Thanks to the intervention of #user2495207 the menu works as I wanted! I tried to put everything on my website (I have it in the header menu), it opens and closes with the button, but when I click outside the div it doesn't close.
As you can see here it works. Am I missing something?
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>
If you inspect the .mts_mob_container element in your browser you'll realize it's covering the button (the button isn't triggering any event) so i had to comment its dimensions:
.mts_mob_container {
display: flex;
position: fixed;
z-index: 999;
/* height: 100%; */
top: 0;
left: 0;
/* width: 100%;*/
}
I also added this block, an event when the user clicks outside the sidenav, the code inside is the same as the else part of the mobile_menu function to close the 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);
}
});
UPDATE:
The button event was propagating to its parent document so i added e.stopPropagation();.
In the event of the document; the if statement if(e.target.id !== "mts_mobile_menu" && x.classList.contains("side_show")) means that it'll execute if the target clicked isn't the sidenav and is showed
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>

How to calculate the element scroll height and scroll when move mouse in another element

i'm trying to create a select list and custom scrollbar what i did at the first is when the user scrolling the element the custom scrollbar move to the scolled position normally without any problem you can find it at this fiddle
now i want to hide the browser scrollbar and apply scolling inside the select menu from this custom scroll bar i tried the following
let scrollbarConatiner = document.getElementsByClassName('scrollbar-conatiner')[0],
menuItemsContainer = document.getElementsByClassName("menu-items-container")[0]
scrollbarConatiner.addEventListener("mousemove", function(e) {
let scrollbar = this.getElementsByClassName("scrollBar")[0]
let y = e.offsetY
console.log(menuItemsContainer.scrollHeight, menuItemsContainer.clientHieght, e.offsetY)
menuItemsContainer.scrollTop = y;
})
but it's scrolling just for the clientHieght when i want it to scroll and move the scrollbar to the menuItemsContainer scrollHeight i don't know the right way to apply this custom scrolling can anyone help me to make it work
here's the whole code
HTML
<div id="select">choose...</div>
<div id="select-menu">
<!-- Scrollbar -->
<div class="scrollbar-conatiner">
<div class="scrollbar"></div>
</div>
<!-- menu items -->
<div class="menu-items-container">
<div class="menu-items">
<span>Facebook</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>YouTube</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Twitter</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Pinterest</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Instagram</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Raddit</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Facebook</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>YouTube</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Twitter</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Pinterest</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Instagram</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Raddit</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Facebook</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>YouTube</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Twitter</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Pinterest</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Instagram</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
<div class="menu-items">
<span>Raddit</span>
<span class="circle">
<span class="circlein"></span>
</span>
</div>
</div>
</div>
CSS
body {
font-family: sans-serif;
}
#select {
background: #1c1d22;
color: #999;
width: 80%;
padding: 20px 20px 20px 20px;
margin: auto;
font-size: 14px;
position: relative;
}
#select:before {
content: "";
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-top: 10px solid #818181;
position: absolute;
right: 20px;
top: 42%;
}
#select-menu {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
text-align: center;
display: none;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.6)
}
.menu-items-container {
background: dodgerblue;
width: 90%;
overflow: hidden;
max-height: 360px;
}
.menu-items {
text-decoration: none;
color: #fff;
display: block;
padding: 20px 90px 20px 20px;
text-align: left;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
position: relative;
}
.menu-items:hover {
background: #333
}
.menu-items:hover .circle {
box-shadow: 0 0 3px 4px rgba(233, 244, 255, 0.3);
top: 30%
}
.circle {
border-radius: 50%;
height: 20px;
width: 20px;
border: 1px solid #fff;
position: absolute;
top: 33%;
right: 25px;
display: flex;
align-items: center;
justify-content: center;
}
.circlein {
border-radius: 50%;
height: 65%;
width: 65%;
background: skyblue;
display: none;
}
.scrollbar-conatiner {
position: absolute;
width: 12px;
border-radius: 35px;
background: rgba(30, 30, 30, 0.3);
right: 5%;
overflow: hidden;
z-index: 1;
}
.scrollbar {
height: 30%;
width: 100%;
border-radius: 35px;
background: #333;
position: absolute;
cursor: pointer;
z-index: 2;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
JS
let select = document.getElementById('select'),
selectMenu = document.getElementById("select-menu"),
menuItemsContainer = document.getElementsByClassName("menu-items-container")[0],
menuItems = document.getElementsByClassName("menu-items"),
scrollbarConatiner = document.getElementsByClassName('scrollbar-conatiner')[0]
//show scrollbar only when elements more than 6
if (menuItems.length > 6) {
scrollbarConatiner.style.display = 'block'
} else {
scrollbarConatiner.style.display = 'none'
}
select.addEventListener('click', function() {
//select menu
selectMenu.style.display = 'flex'
//scrollbar
scrollbarConatiner.style.height = menuItemsContainer.offsetHeight + "px";
//select-menu items
menuItemsContainer.style.opacity = 1;
menuItemsContainer.style.transition = '0.5s';
});
$(".menu-items").click(function() {
//select-menu
selectMenu.style.display = 'none'
//set text of choosed element
select.innerText = this.innerText.trim()
//add circle for choosed
$(".circlein").hide();
$(this).find(".circlein").show(10)
});
$("#select-menu").click(function(e) {
if (e.target.id === $(this).attr("id")) {
$(this).fadeOut(40);
}
});
menuItemsContainer.addEventListener('scroll', function() {
var y = menuItemsContainer.scrollTop;
var z = menuItemsContainer.scrollHeight - menuItemsContainer.clientHeight;
var q = (y / z) * 70
$(".scrollbar").css({
top: q + "%"
})
});
scrollbarConatiner.addEventListener("mousemove", function(e) {
let scrollbar = this.getElementsByClassName("scrollBar")[0]
let y = e.offsetY
console.log(menuItemsContainer.scrollHeight, e.offsetY, menuItemsContainer.clientHeight)
menuItemsContainer.scrollTop = y;
})

Categories