I have designed a menu for my WordPress site.
My menu has two main problems:
1- When I click on the icon, the ".back" class, which puts gray color on the whole screen, becomes black. so that the background becomes completely black.
2- The second problem is related to when I click on the gray area.
When on the body with the ".back" class. I made it, I click it, the menu closes, but the icon does not return to the previous state.
I put the codes that I wrote below so that you can better understand my problem and I hope you can help me in solving this problem.
Thanks.
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "25%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = "-300px";
}
$('body').append('<div class="back"></div>')
$('.back').click(function() {
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
$(this).remove();
});
});
.main_menu {
position: absolute;
top: 0;
left: -300px;
bottom: 0;
z-index: 999;
background: #eee;
padding-right: 2rem;
transition: all 1s ease;
}
.icon_menu {
position: fixed;
top: 10%;
left: 2%;
font-size: 40px;
color: #a66fff;
cursor: pointer;
z-index: 99999;
transition: all 1s ease;
}
.main_menu ul {
list-style: none;
line-height: 60px;
font-size: 35px;
}
.main_menu ul li a {
color: #000000;
text-decoration: none;
padding-right: 15px;
padding-left: 40px;
margin-left: -60px;
margin-bottom: 10px;
}
.back {
width: 100%;
height: 100%;
position: fixed;
z-index: 9 !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #00000056;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.10.3/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<nav id="nav">
<span class="bi bi-grid-fill icon_menu"></span>
<aside class="main_menu">
<ul>
<li>
<a href="#">
home
</a>
</li>
<li>
<a href="#">
our articles
</a>
</li>
<li><a href="#">
about us
</a>
</li>
</ul>
</aside>
</nav>
</section>
Your first issue is caused because you keep adding/removing the element. This is bad practice, and inside you should just call .toggle() to hide/show it instead.
Your second issue is caused because you do only change the classes when the button is clicked, not the background.
Try this code instead:
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
$('.back').hide();
$('.back').click(function() {
if ($(this).is(':hidden')) return;
$(this).toggle();
icon.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
});
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "25%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = "-300px";
}
$('.back').toggle();
});
.main_menu {
position: absolute;
top: 0;
left: -300px;
bottom: 0;
z-index: 999;
background: #eee;
padding-right: 2rem;
transition: all 1s ease;
}
.icon_menu {
position: fixed;
top: 10%;
left: 2%;
font-size: 40px;
color: #a66fff;
cursor: pointer;
z-index: 99999;
transition: all 1s ease;
}
.main_menu ul {
list-style: none;
line-height: 60px;
font-size: 35px;
}
.main_menu ul li a {
color: #000000;
text-decoration: none;
padding-right: 15px;
padding-left: 40px;
margin-left: -60px;
margin-bottom: 10px;
}
.back {
width: 100%;
height: 100%;
position: fixed;
z-index: 9 !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #00000056;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.10.3/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<nav id="nav">
<span class="bi bi-grid-fill icon_menu"></span>
<aside class="main_menu">
<ul>
<li>
home
</li>
<li>
our articles
</li>
<li>about us
</li>
</ul>
</aside>
</nav>
</section>
<div class="back"></div>
Related
My goal is something similar to what YouTube has when you click their menu icon; the rest of the page gets darker and nothing on that part of the page is accessible to the user until the button is clicked again and the menu recedes. Any help with this would be greatly appreciated.
<!DOCTYPE html>
<body lang = 'en-US'>
<head>
<meta charset = 'UTF-8'>
<meta http-equiv = 'X-UA-Compatible' content = 'IE = edge'>
<meta name = 'viewport' content = 'width = device-width, initial-scale = 1'>
<title>Testing</title>
<!-- links to relative files -->
<link rel = 'stylesheet' href = '/Custom_Scrollbar.CSS'>
<link rel = 'shortcut icon' type = 'image/png' href = '/Images/Odd_Jobs_Favicon.png'>
</head>
<body>
<div class = 'headerBar'>
<style>
.headerBar {
position: absolute;
width: 100%;
height: 80px;
top: 0px;
left: 0px;
background-color: #e0e0e0;
}
</style>
</div>
<div class = 'headerStrip'>
<style>
.headerStrip {
position: absolute;
width: 100%;
height: 5px;
top: 80px;
left: 0px;
background-color: #5e00bc
}
</style>
</div>
<div class = 'bodyBar'>
<style>
.bodyBar {
position: absolute;
width: 100%;
height: 100%;
top: 85px;
left: 0px;
background-color: #000000
}
</style>
</div>
<div class = 'jobLinks'>
<li><a class = 'find' href = '#'>Link</a></li>
<style>
.jobLinks {
text-decoration: none;
list-style: none;
}
.find {
position: absolute;
width: 80px;
height: 40px;
top: 30px;
left: 300px;
font-family: 'comfortaa';
font-size: 18px;
font-weight: 800;
color: #000000;
text-decoration: none;
text-align: center;
transition: ease-out 0.4s;
background-color: #e0e0e0;
}
.find:hover {
color: #5e00bc;
}
</style>
</div>
<div class = 'menu'>
<button class = 'menuButton'></button>
<div class = 'linkList'>
<ul>
<li><a class = 'links' href = '#'>Link 1</a></li>
<li><a class = 'links' href = '#'>Link 2</a></li>
<li><a class = 'links' href = '#'>Link 3</a></li>
<li><a class = 'links' href = '#'>Link 4</a></li>
<li><a class = 'links' href = '#'>Link 5</a></li>
<li><a class = 'links' href = '#'>Link 6</a></li>
<li><a class = 'links' href = '#'>Link 7</a></li>
</ul>
</div>
<style>
.menuButton {
position: absolute;
width: 30px;
height: 30px;
top: 25px;
left: 1303px;
border: none;
outline: none;
transition: ease-out 0.5s;
background-image: url('/Images/Menu_Icon.png');
background-color: #e0e0e0;
cursor: pointer;
}
.links {
font-family: 'comfortaa';
font-size: 18px;
font-weight: 500;
color: #000000;
text-decoration: none;
transition: ease-out 0.4s;
}
.links:hover {
color: #5e00bc;
}
.linkList {
position: fixed;
width: 150px;
height: 100%;
right: -150px;
top: 85px;
transition: ease-out 0.5s;
background: #e0e0e0;
}
.linkList ul li {
list-style: none;
padding: 15px;
}
.menuButton:focus ~ .linkList {
right: 0px;
}
</style>
<script>
menuBtn = document.getElementsByClassName('menuButton')[0];
menuBtn.addEventListener('click', function() {
menu = document.getElementsByClassName('linkList')[0];
menu.style.webkitTransition = '0.6s';
if (menu.style.right == '0px') {
menu.style.right = '-150px';
} else {
menu.style.right = '0px';
}
});
</script>
</div>
</body>
</html>
It can be achieved by some css and js.
I am adding menuOpen class when the menu is open. and removing it when the menu is closed.
menuOpen class css is setting other content besides menu unaccesseiable.
const open = document.querySelector("#open");
const close = document.querySelector("#close");
const menu = document.querySelector("#menu");
open.addEventListener("click", () => {
menu.classList.add("active");
document.body.classList.add("menuOpen");
});
close.addEventListener("click", () => {
menu.classList.remove("active");
document.body.classList.remove("menuOpen");
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
position: relative;
overflow-x: hidden;
}
#menu {
display: flex;
flex-direction: column;
gap: 15px;
width: 100px;
position: absolute;
top: 0;
left: -100px;
background-color: #f5f5f5;
padding: 20px;
transition: .5s;
}
#menu.active {
left: 0;
}
.menuOpen {
position: relaive;
transition: .5s;
}
.menuOpen::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000;
opacity: 0.5;
height: 100vh;
width: 100vw;
overflow: hidden;
}
<button id="open">open</button>
<div id="menu">
<button id="close">close</button>
<button>a</button>
<button>a</button>
<button>a</button>
</div>
<p>content</p>
I have this navigation menu as in the image here.
Below is my JS that I currently have to make it responsive so that it opens up on clicking it but it is not working:
function showMenu(event) {
event.preventDefault();
let element = document.getElementById('header');
if (element.classList.contains('active')) {
element.className = "";
} else {
element.className = "active";
}
}
header {
padding: 0 !important;
background: #fff;
}
header.active {
box-shadow: 0 1px 5px 1px rgba(0, 0, 0, 0.2);
}
header.fixed {
padding: 0 0;
}
header button {
position: absolute;
top: 12px;
right: 25px;
display: block;
width: 30px;
height: 40px;
padding-top: 6px;
border: none;
background: #fff;
}
header button span {
position: relative;
top: 0;
display: block;
width: 100%;
height: 2.5px;
margin-bottom: 5px;
transition: all .2s ease;
border-radius: 15px;
background: #0d2366;
}
header button span:nth-child(2) {
right: 0;
width: 80%;
opacity: 1;
}
header button span:nth-child(3) {
width: 60%;
}
header.active button span:nth-child(1) {
top: 8px;
left: -4px;
-ms-transform: rotate(38deg);
transform: rotateZ(38deg);
}
header.active button span:nth-child(2) {
right: -100%;
opacity: 0;
}
header.active button span:nth-child(3) {
top: -6px;
left: -4px;
width: 100px;
-ms-transform: rotate(-38deg);
transform: rotateZ(-38deg);
}
header ul.menu-left {
display: none;
}
header img {
margin-left: 25px !important;
}
header.active ul.menu-left {
display: block;
float: none;
clear: both;
}
header.active ul.menu-left li {
display: block !important;
padding: 10px 20px;
}
header ul.menu-right {
display: none;
}
<!--Header-->
<header id="header">
<div class="wrapper">
<a href="/">
<img src="images/pulse.png" alt="logo">
</a>
<button id="submenu">
<span></span>
<span></span>
<span></span>
</button>
<!--Menu Links-->
<ul class="menu-left">
<li>Home</li>
<li>About</li>
<li>Services</li>
<li>Pricing</li>
<li>Contact</li>
</ul>
<ul class="menu-right">
<li class="menu-cta">Get Started</li>
</ul>
</div>
</header>
The active class here represents the responsive menu icon.
Any help is highly appreciated.
Thanks!
By using the addEventListener you can watch the click event. After clicking the button, the third line below will toggle between adding and removing the class 'active' on the id="header"
document.getElementById("submenu").addEventListener("click", function(event) {
event.preventDefault();
document.getElementById("header").classList.toggle("active");
});
I working on this sliding menu. It can slide fine, but have problem to close it by clicking x.
let openNav = document.querySelector(".slideOpen");
let closeNav = document.querySelector(".slideClose");
document.addEventListener("click", () => {
openNav.style.width = "250px";
});
document.addEventListener("click", () => {
closeNav.style.width = "0";
});
.slideOpen { height: 100%; width: 0; position: fixed; z-index: 1; top: 0; left: 0; background-color: #111; overflow-x: hidden; transition: 0.5s; padding-top: 60px; }
.slideOpen a { padding: 8px 8px 8px 32px; text-decoration: none; font-size: 25px; color: #818181; display: block; transition: 0.3s; }
.slideOpen a:hover { color: #f1f1f1; }
.slideOpen .slideClose { position: absolute; top: 0; right: 25px; font-size: 36px; margin-left: 50px; }
<div style="font-size:30px;cursor:pointer">☰ open</div>
<div class="slideOpen"> <ul>
<li> × </li>
<li> About </li>
<li> Services </li>
<li> Clients </li>
<li> Contact </li>
</ul> </div>
You need to add actionListeners on buttons(links) rather than on document.
let slide = document.querySelector(".slide");
let slideOpen = document.querySelector(".slideOpen");
let slideClose = document.querySelector(".slideClose");
slideOpen.addEventListener('click', function(event) {
slide.style.width = "250px";
});
slideClose.addEventListener("click", () => {
slide.style.width = "0";
});
.slide { height: 100%; width: 0; position: fixed; z-index: 1; top: 0; left: 0; background-color: #111; overflow-x: hidden; transition: 0.5s; padding-top: 60px; }
.slide a { padding: 8px 8px 8px 32px; text-decoration: none; font-size: 25px; color: #818181; display: block; transition: 0.3s; }
.slide a:hover { color: #f1f1f1; }
.slide .slideClose { position: absolute; top: 0; right: 25px; font-size: 36px; margin-left: 50px; }
<div style="font-size:30px;cursor:pointer" class="slideOpen">☰ open</div>
<div class="slide"> <ul>
<li> × </li>
<li> About </li>
<li> Services </li>
<li> Clients </li>
<li> Contact </li>
</ul> </div>
You are making addEventListener to the whole document instead make to particular element (open and close)..
Changes:
Added a new class openMenu in the open menu element like,
<div style="font-size:30px;cursor:pointer" class="openMenu">☰ open</div>
Then added a new variable to store the element like,
let open = document.querySelector(".openMenu");
Then modified document.addEventListener with open and closeNav respectively like,
open.addEventListener("click", () => {
openNav.style.width = "250px";
});
closeNav.addEventListener("click", () => {
openNav.style.width = "0";
});
And the changed snippet looks like,
let openNav = document.querySelector(".slideOpen");
let open = document.querySelector(".openMenu");
let closeNav = document.querySelector(".slideClose");
open.addEventListener("click", () => {
openNav.style.width = "250px";
});
closeNav.addEventListener("click", () => {
openNav.style.width = "0";
});
.slideOpen { height: 100%; width: 0; position: fixed; z-index: 1; top: 0; left: 0; background-color: #111; overflow-x: hidden; transition: 0.5s; padding-top: 60px; }
.slideOpen a { padding: 8px 8px 8px 32px; text-decoration: none; font-size: 25px; color: #818181; display: block; transition: 0.3s; }
.slideOpen a:hover { color: #f1f1f1; }
.slideOpen .slideClose { position: absolute; top: 0; right: 25px; font-size: 36px; margin-left: 50px; }
<div style="font-size:30px;cursor:pointer" class="openMenu">☰ open</div>
<div class="slideOpen"> <ul>
<li> × </li>
<li> About </li>
<li> Services </li>
<li> Clients </li>
<li> Contact </li>
</ul> </div>
For some reason on my mobile menu the font-size of links changes when i revisit the page. I have another page that uses the exact same javascript and CSS and the font size of the links does not change when you revist, taht page does not have iframes, so I'm assuming it's linked with the fact the page where the font size changes has iframes
It does not change when i test it using dev tools on a browser but when testing on my Iphone X it does seem to change i'll attach a video of this where you can see when I revist the page the font sizer appears smaller and when clicking on one of the links padding or margin seems to increase
for some reason
Here is the video in the form of a gif file
https://giphy.com/gifs/RMGsA6Dg4Y9p6IvE4E
var iframes = document.getElementsByTagName('iframe');
var form = document.getElementsByTagName('form');
function toggleMobileMenu(){
//show menu
if(document.getElementById("testingdrop").style.visibility != "visible"){
document.getElementById("testingdrop").style.visibility = "visible";
document.getElementById("testingdrop").style.transition = "0.5s";
document.getElementById("testingdrop").style.width = "55%";
document.getElementById("dropdownIcon").style.color = "#ffc800";
//get all iframes elements and change opacity
for(var i=0; i<frames.length; i++){
iframes[i].style.opacity = "0.5";
}
}
//hide menu
else{
document.getElementById("testingdrop").style.visibility = "hidden";
document.getElementById("testingdrop").style.width = "200%";
document.getElementById("dropdownIcon").style.color = "black";
for(var i=0; i<frames.length; i++){
iframes[i].style.opacity = "1";
}
}
}
HTML
<div class="dropdown" id="testingdrop">
<ul>
<li>HOME</li>
<li>VIDEOS</li>
<li>ENQUIRIES</li>
<li>INSTAGRAM</li>
<li id="debByListItem">A WEBSITE BY <br>#UMARMIAHFAROOQ</li>
</ul>
</div>
CSS
#testingdrop{
visibility: hidden;
text-decoration: none;
color: black;
font-family: 'Raleway', sans-serif;
display: grid;
grid-template-columns: 55% auto;
grid-template-rows: 29em;
padding-bottom: 20px;
position: fixed;
z-index: 1;
transition: 0.5s;
width: 200%;
}
li{
list-style-type: none;
padding-bottom: 3px;
padding-left: 4px;
left: -11.4%;
grid-column-start: 2;
transition: margin-left .5s;
z-index: 2;
}
ul{
width: 100%;
left: 3px;
grid-column-start: 2;
padding-bottom: 560%;
padding-right: 82%;
background: white/*#171717*/;
transition: margin-left .5s;
z-index: 2;
}
.mobilemenu{
text-decoration: none;
color: black;
grid-column-start: 2;
z-index: 2;
}
#devBy{
color: #ffc800;
font-size: 40%;
z-index: 2;
}
#debByListItem{
margin-top: 10%;
z-index: 2;
}
It looks all fine. maybe you've missed some style:
var iframes = document.getElementsByTagName("iframe");
var form = document.getElementsByTagName("form");
function toggleMobileMenu() {
//show menu
if (document.getElementById("testingdrop").style.visibility != "visible") {
document.getElementById("testingdrop").style.visibility = "visible";
document.getElementById("testingdrop").style.transition = "0.5s";
document.getElementById("testingdrop").style.width = "55%";
document.getElementById("dropdownIcon").style.color = "#ffc800";
//get all iframes elements and change opacity
for (var i = 0; i < frames.length; i++) {
iframes[i].style.opacity = "0.5";
}
} else {
//hide menu
document.getElementById("testingdrop").style.visibility = "hidden";
document.getElementById("testingdrop").style.width = "200%";
document.getElementById("dropdownIcon").style.color = "black";
for (var i = 0; i < frames.length; i++) {
iframes[i].style.opacity = "1";
}
}
}
#testingdrop {
visibility: hidden;
text-decoration: none;
color: black;
font-family: "Raleway", sans-serif;
display: grid;
grid-template-columns: 55% auto;
grid-template-rows: 29em;
padding-bottom: 20px;
position: fixed;
z-index: 1;
transition: 0.5s;
width: 200%;
}
li {
list-style-type: none;
padding-bottom: 3px;
padding-left: 4px;
left: -11.4%;
grid-column-start: 2;
transition: margin-left 0.5s;
z-index: 2;
}
ul {
width: 100%;
left: 3px;
grid-column-start: 2;
padding-bottom: 560%;
padding-right: 82%;
background: white;
transition: margin-left 0.5s;
z-index: 2;
}
.mobilemenu {
text-decoration: none;
color: black;
grid-column-start: 2;
z-index: 2;
}
#devBy {
color: #ffc800;
font-size: 40%;
z-index: 2;
}
#debByListItem {
margin-top: 10%;
z-index: 2;
}
<div class="dropdown" id="testingdrop">
<ul>
<a href="./Home.html" class="mobilemenu">
<li>HOME</li>
</a>
<a href="./videos.html" class="mobilemenu">
<li>VIDEOS</li>
</a>
<a href="./enquiry.html" class="mobilemenu">
<li>ENQUIRIES</li>
</a>
<a href="https://www.instagram.com/thegreatmurshed/" class="mobilemenu">
<li>INSTAGRAM</li>
</a>
<a href="https://www.instagram.com/umarmiahfarooq/" class="mobilemenu" id="devBy">
<li id="debByListItem">A WEBSITE BY <br>#UMARMIAHFAROOQ</li>
</a>
</ul>
</div>
Toggle Menu
function openNav() {
document.getElementsByClassName("menu-overlay").style.width = "50%";
}
function closeNav() {
document.getElementsByClassName("menu-overlay").style.width = "0";
}
.menu-overlay {
display: none;
top: 0;
height: 100%;
width: 0%;
position: absolute;
z-index: 1;
right: 0;
background-color: #ef4f50;
overflow-x: hidden;
transition: 0.5s;
}
.menu-body{
position: fixed;
top: 0;
z-index: 99999;
right: 0;
height: 100%;
background-color: #ef4f51;
width: 35%;
float: right;
}
span.closer {
font-size: 50px;
float: right;
color: white;
padding: 30px;
}
.menu-pan{
width: 100%;
float: left;
padding: 0 80px;
}
.menu-pan li {
padding: 10px 0;
}
.menu-pan li a {
color: white;
text-decoration: none;
font-size: 32px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/simple-line-icons/2.4.1/css/simple-line-icons.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div class="header-top clearfix">
DONATE NOW
<a class="l-right toggle-menu" href="#" onclick="openNav()">
<span class="icon-menu"></span>
</a>
</div>
<div class="menu-overlay">
<div class="menu-body">
<span class="closer"><i class="icon-close icons" onclick="closeNav()"></i></span>
<ul class="menu-pan">
<li>Home</li>
<li>About</li>
<li>Our Purpose</li>
<li>HOME</li>
<li>Contact</li>
</ul>
</div>
</div>
</header>
hello this is my menu bar code.i want my navigation bar to be open when i click on the hamburger icon from right side with transition (smooth) effect with width 50% & remaining part will be overlay.
"https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_overlay" this link has the same effect but from left right.
getElementsByClassName function returns an array so using getElementsByClassName("menu-overlay").style would be incorrect. Instead use it like so:
function openNav() {
document.getElementsByClassName("menu-overlay")[0].style.width = "50%";
}
function closeNav() {
document.getElementsByClassName("menu-overlay")[0].style.width = "0";
}