How to close Hamburger menu with close icon - javascript

I have set up a hamburger menu with a close icon already. I'm just not sure how to just turn off the hamburger menu with a simple click. Only thing I've been able to do is just reload the page completely. Perhaps there is some jquery that could be used to solve this issue.
The close menu button is item 1 in the menu list.
Here is my code.
<div class="menu-wrapper">
<nav>
<ul class="header-menu">
<li><i class="far fa-window-close"></i></li>
<li class="current">Home</li>
<li>Prints</li>
<li>Blog</li>
<li>Tutorials</li>
<li>Sports</li>
</ul>
</nav>
</div>
CSS:
#menu-icon {
display: hidden;
width: 40px;
height: 40px;
background: url(../img/menu-icon.png) center;
text-decoration: none;
}
#close-menu {
display: none;
}
#media only screen and (max-width: 600px) {
#menu-icon {
display:inline-block;
z-index: 10000;
}
#close-menu {
display: inline-block;
color: black !important;
font-size: 20px !important;
}

OK, here's an example of how to make a burger nav. Fiddle
HTML:
<nav data-state=closed>
<a>×</a>
<a href=something.html>Link 1</a>
<a href=something-else.html>Link 2</a>
<a href=etc.html>Link 3</a>
</nav>
See how we're preparing to toggle the open/closed state with a data attribute. (We could have used a class, but I prefer a DA in this case because it means we can toggle it; with a class, you'd have to remove one class and add anothe, e.g. remove 'closed' and add 'open'.)
The structure is simple; we use a nav element and use the first a within it as the close icon. We use the multiplication (times) entity for this.
CSS:
nav {
position: absolute;
right: 1rem;
top: 2rem;
padding: 1rem;
background-color: #d55 !important;
}
nav[data-state=closed] {
cursor: pointer;
background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Hamburger_icon.svg/220px-Hamburger_icon.svg.png') no-repeat 100%/100%;
width: 50px;
height: 50px;
}
nav a { display: block; }
nav a:not(:first-of-type) { border-bottom: solid 1px rgba(0, 0, 0, .2); padding: .8rem 0; }
nav[data-state=closed] * { display: none; }
nav a:first-of-type {
position: absolute;
right: .2rem;
top: -.1rem;
font-size: 2rem;
cursor: pointer;
font-weight: bold;
}
Now here's the key part, the JS:
//get nav element
let nav = $('nav');
//listen for clicks on it
nav.on('click', evt => {
//...get current state (open vs. closed)
let curr_state = nav.attr('data-state');
//...if open, and click was NOT to close icon (first A tag) ignore click
if (curr_state == 'open' && !$(evt.target).is('a:first-of-type')) return;
//...otherwise toggle state (open it or close it)
nav.attr('data-state', curr_state == 'closed' ? 'open' : 'closed');
})

Related

My nav bar is not working when I click to the burger menu

When I try to click to the burger menu, the navigation bar is not working. What should I do?
I wrote some html code and gave a navigation bar a special Id also I gave ID to the burger menu to use it later in jQuery.
In CSS I gave a parameter when the screen size will be less than 991px it would execute the following.
I also wrote that normally display should be hidden, but when I click to the burger menu the nav class should change from class="nav" to "nav show" but in my case it doesn't change.
let nav = $("#nav");
let navToggle = $("#navToggle");
navToggle.on("click", function(event) {
event.preventDefault();
nav.toggleClass("show");
});
#media (max-width: 991px) {
.works__item {
width: 50%;
}
.burger {
display: flex;
}
.nav {
display: none;
width: 100%;
flex-direction: column;
background-color: #31344e;
text-align: right;
position: absolute;
top: 100%;
right: 0;
}
.nav.show {
display: block;
}
.nav__link {
padding: 9px 15px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<nav class="nav" id="nav">
Features
Works
Our Team
Reviews
Download
</nav>
<button class="burger" type="button" id="navToggle ">
<span class="burger__item">Menu</span>
</button>
Several things
The biggest is the position absolute with values that are not working at all
Also I would not use the same ID and CLASS for the nav - you now have ID, CLASS and TAGNAME all nav
let $nav = $("#nav");
let $navToggle = $("#navToggle");
$navToggle.on("click", function(event) {
event.preventDefault();
$nav.toggleClass("show");
});
.works__item {
width: 50%;
}
.burger {
display: flex;
}
.nav {
display: none;
width: 100%;
flex-direction: column;
background-color: #31344e;
text-align: right;
position: relative;
}
.nav a { color:white;}
.nav.show {
display: block;
}
.nav__link {
padding: 9px 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<nav class="nav" id="nav">
Features
Works
Our Team
Reviews
Download
</nav>
<button class="burger" type="button" id="navToggle">
<span class="burger__item">Menu</span>
</button>
You can do this more shortly like the following piece of code.
navToggle.on('click', function() {
nav.toggle();
});
If you wish (and maybe it's already done) you can check the jquery documentation to fully understand how "toggle()" function work. https://api.jquery.com/toggle/

Why isn't the navigation showing from top to bottom but rather left to right

Here is the snippet:
const exitBtn = document.querySelector('#exitBtn');
menuBtn.addEventListener('click', () => {
const menu = document.querySelectorAll('.menu');
for (let el of menu) {
el.style.display = 'block'
}
})
#media (max-width: 934px) {
.max-width {
padding: 0 50px;
}
.fa.fa-bars.menuBtn {
display: block;
}
.menu {
position: fixed;
height: 100vh;
width: 100%;
left: 0;
top: 0;
background-color: #111;
text-align: center;
padding-top: 110px;
}
.exit {
z-index: 999;
display: none;
margin: 1.8rem;
}
.menu ul li {
display: block;
}
.menu li a {
display: inline-block;
margin: 20px 0;
font-size: 35px;
}
}
<header>
<nav class="navbar" id="nav">
<div class="max-width">
<div class="logo"><a id="headSpan" href="index.html">Port<span>folio.</span></a></div>
<div class="menu">
<ul>
<li>Home</li>
<li>About</li>
<li>Skills</li>
<li>Projects</li>
<li>CV</li>
<li>Contact</li>
</ul>
</div>
<div>
<i class="fa fa-bars menuBtn" id="menuBtn" aria-hidden="true"></i>
</div>
<div class="exit">
<i class="fa fa-times-circle exit" id="exitBtn" aria-hidden="true"></i>
</div>
</div>
</nav>
I tried making it block but it did not work, I also tried making flex-direction to be column but still did not work. Am I doing something wrong somewhere? What is causing the issue of the menu not being displayed from up to down? Is there an alternative way to go about this?
Maybe try to set the position of the navbar class to fixed if it is a sidebar you are trying to do, or as how I perceive, you are trying to make a menu bar on the side supposedly and not a rowline. Then the class of menu should be the one flexed and not fixed. You are supposed to make a container for the menu that is the fixed one so that all of its content will be fixed on the side. Show me more of the css and I might help. But try doing
.navbar{
width: width;
height: 100vh;
position: fixed;}
Then the "max-width" class will have the flex attribute
.max-width{
display: flex;
flex-direction: column;}

mobile navbar not collapsing

I want the navbar to disappear when it reaches 768px and become a button on the right side. The button will open the navbar back, I have added code to make the navbar to disappear at 768px but it doesn't work. Not so sure what is wrong since the button shows 768px. But the navbar does not disappear at 768px.
html
<nav id="Nav" class="navbar nav">
<div class="container flex">
<img src="Week5saasappassets-210323-142515 (1)/Week-5-saas-app-assets/project_logo/logo.svg" alt="Company logo" class="company-logo">
<button class="navbar-toggler" aria-expanded="false" aria-controls="navbarDropdown"><span>☰</span></button>
<div class="nav-parent">
<ul class="navbar-nav">
<li class="nav-link">
Home
</li>
<li class="nav-link">
Features
</li>
<li class="nav-link">
Learn
</li>
<li class="nav-link">
Price
</li>
<li class="nav-link">
Hire us
</li>
</ul>
</div>
</div>
</nav>
css
navbar-toggler{
position: absolute;
right: var(--size-20);
outline: none;
background-color: transparent;
border: 1px solid transparent;
}
.navbar-toggler span{
color: var(--pureblack);
font-size: var(--size-20);
}
[aria-controls="navbarDropdown"]{
display: none;
}
.navbar .container{
top: 0;
right: 0;
left: 0;
z-index: 500;
transition: ease-in-out 0.3s;
display:flex;
align-items: center;
}
.navbar-brand{
cursor: pointer;
}
.nav-parent{
margin-left: auto;
}
.navbar-nav{
display: flex;
align-items: center;
}
.navbar-nav li{
align-items: center;
}
.nav-link a{
margin-right: 2.5rem;
}
responsive
#media screen and (max-width: 768px) {
[aria-controls="navbarDropdown"] {
display: block;
}
[aria-expanded="false"] ~ ul{
display: none;
}
[aria-expanded="true"] ~ ul{
display: block;
}
}
javascript
<script>
const navButton = document.querySelector('button[aria-expanded]');
function toggleNav({ target }){
const expanded = target.getAttribute('aria-expanded') === 'true' || false;
navButton.setAttribute('aria-expanded', !expanded);
}
navButton.addEventListener('click', toggleNav);
</script>
Your css to select the ul via the button,
[aria-expanded="false"] ~ ul{
display: none;
}
[aria-expanded="true"] ~ ul{
display: block;
}
Won't work, here's why. The tilde (~) is a sibling selector. For this selector to work the way you specified, your ul would have to appear after the button, within the same container, like this:
<button ariaexpanded="true"></button>
<ul class="navbar-nav">
<li class="nav-link">
Home
</li>
</ul>
So if your .nav-parent div isn't being used, you could try remove that and it will likely work.
This is my approach when doing mobile menus. Have your media query target a certain container which goes to 100% viewport width and height at your mobile breakpoint. It should also be offset vertically or horizontally out of the view of the user. Then you just need some JS to toggle a 'showing' class which positions the menu on the user's screen:
Your toggle nav function:
function toggleNav({ target }){
const expanded = target.getAttribute('aria-expanded') === 'true' || false;
navButton.setAttribute('aria-expanded', !expanded);
// Toggle nav 'showing' class
if (nav.classList.contains('showing')) {
nav.classList.remove('showing')
} else {
nav.classList.add('showing')
}
}
// Close menu button
closeNavButton.addEventListener('click', () => {
nav.classList.remove('showing')
})
CSS:
/* Don't show the 'close' button on desktop */
.nav-parent button {
display: none;
}
/* Mobile breakpoint */
#media screen and (max-width: 768px) {
[aria-controls="navbarDropdown"] {
display: block;
}
[aria-expanded="false"] ~ ul{
display: none;
}
/* Your menu now takes up 100% of screen, and is offset to the left */
.nav-parent {
opacity: 0;
position: absolute;
height: 100vh;
width: 100vw;
top: 0;
left: -100vw;
transition: all 0.25s ease;
background: white;
}
/* When the showing class is added, it will position itself on the screen */
.nav-parent.showing {
opacity: 1;
left: 0;
}
}
HTML (add a close-menu button)
<div class="nav-parent">
<button>
Close
</button>
<ul class="navbar-nav">
...
</div>
JSfiddle demo
There's lots of room for creativity.

Can't get my main nav to perform as a sticky nav

I've created a utility and main navigation bar for this self-project I'm working on, and I want the main nav to become sticky when I scroll 42px.
However, when I scroll the navigation bar doesn't stick at the top of the window. I tested it with the utility nav, and it worked perfectly. Here is my coding for the main nav bar...
$(window).on("scroll", function () {
var distanceScrolled = $(window).scrollTop();
console.log("The distance scrolled is: " + distanceScrolled);
if(distanceScrolled>42){
$("#main-nav").addClass("scrolled");
}
else{
$("#main-nav").removeClass("scrolled");
}
});
#main-nav {
position: relative;
width: 100%;
height: 100px;
background-color: #000000;
}
.main-nav-left {
list-style: none;
float: left;
padding-left: 28px;
height: 100px;
}
.main-nav-items {
position: absolute;
top: 40%;
left: 290px;
list-style: none;
text-decoration: none;
}
.main-nav-items li {
display: inline-block;
padding-right: 12px;
margin-right: 13px;
}
.main-nav-right li {
float: right;
padding-right: 12px;
margin-right: 26px;
margin-top: 40px;
list-style: none;
}
#main-nav a {
text-decoration: none;
color: #ffffff;
}
.scrolled {
position: fixed;
top: 0;
z-index: 1000;
}
<nav id="main-nav">
<ul class="main-nav-left">
<li><img src="images/thule_logo.png" height="100" width="auto"></li>
</ul>
<ul class="main-nav-items">
<li>CARRIERS & RACKS</li>
<li>ACTIVE WITH KIDS</li>
<li>LUGGAGE & BAGS</li>
<li>SLEEVES & CASES</li>
<li>EXPLORE THULE</li>
</ul>
<ul class="main-nav-right">
<li><i class="fas fa-search fa-lg"></i></li>
</ul>
</nav>
<script src="js/jquery-v3.3.1.js"></script>
<script src="js/main.js"></script>
First of all there is no 'nav' class defined for your html nav element. So in jQuery selector, you need to select by the id(main-nav) as you have defined or by HTML nav element itself. you can do this:
if(distanceScrolled>42){
$("nav").addClass("scrolled");
}
else{
$("nav").removeClass("scrolled");
}
or
if(distanceScrolled>42){
$("#main-nav").addClass("scrolled");
}
else{
$("#main-nav").removeClass("scrolled");
}
But add jQuery library file prior to your custom script.
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
second and the most important thing is that you are adding a class(scrolled) having {position:fixed}. Since Id has higher priority than Class so it won't allow class to overwrite the common CSS property, like in this case 'position'. So you can add !important to class selector's property:
.scrolled{
position:fixed!important;
top: 0;
z-index: 1000;
}
or
write deep CSS selection to make it's priority higher than Id. Like:
#main-nav.scrolled {
position:fixed;
top: 0;
z-index: 1000;
}
Both will work.

Menu won't slide back up once user go to new page

I'm creating a web app that has a custom responsive menu. It's just your basic three list-item menu dropdown. When user clicks "hamburger" icon, it slides down. When they click on the "X", it slides up.
The problem having is that when the user clicks the "hamburger" icon in the mobile menu's closed state and then they click another link on the page outside of the mobile menu, the menu stays in its open/slid down state and becomes unusable unless the user reloads the page.
What do I need to put in my JS function or my CSS to prevent this behavior? I appreciate the help.
The code:
HTML:
<nav class="home-header-content__nav--menu">
<ul>
<li>About</li>
<li>Terms</li>
<li>Help</li>
</ul>
</nav>
<nav class="home-header-content__nav--mobile-menu">
<i class="fa fa-bars"></i>
<i class="fa fa-times"></i>
<ul>
<li>About</li>
<li>Terms</li>
<li>Help</li>
</ul>
</nav>
CSS (only the relevant stuff):
.home-header-content__nav--menu {
#media (max-width: $site-screen__iphone5s--landscape + 1px) {
display: none;
}
}
.home-header-content__nav--mobile-menu {
display: none;
text-align: right;
position: relative;
.fa {
font-size: 28px;
&:hover {
color: $site-color__secondary;
#include transition(0.2s ease-in);
cursor: pointer;
}
}
.fa-times {
display: none;
}
ul {
text-align: right;
font-weight: 700;
position: absolute;
top: 40px;
right: 0px;
background-color: $site-color__secondary;
border-radius: 5px;
padding: 10px 10px 10px 20px;
font-size: 18px;
}
a {
color: $site-color__white;
&:hover {
color: $site-color__secondary--darker;
}
}
#media (max-width: $site-screen__iphone5s--landscape) {
display: inline-block;
}
}
Javascript:
$(function responsiveHomeMenu(){
// Store content nodes in DOM
var $menuIcon = $('.home-header-content__nav--mobile-menu .fa');
var $menuList = $('.home-header-content__nav--mobile-menu ul');
// Hide menu links by default
$menuList.hide();
// Toggle menu with icon
$menuIcon.on("click", function(e){
$menuIcon.toggle();
$menuList.slideToggle(300);
$(document).off("click",function(){
$menuList.toggle();
})
});
});
Try this
// Toggle menu with icon
menuIcon.on("click", function(e){
menuIcon.slideToggle();
menuList.slideToggle(300);
});
$(document).on("click",function(){
menuList.slideUp();
});
});

Categories