Why my JS code isnt enabling the Nav list toggle - javascript

https://codepen.io/brunhild_912/pen/MWQPErp
Here is my code. I am trying to enable the nav list toggle, but its not happening. Why? Any guidance or tips over this issue ae welcomed. I have tried many options but its being stubborn unfortunately.
HTML
<button type="button" class="nav-toggler">
<span></span>
</button>
<!--Navbar-->
<nav class="nav">
<ul>
<li class="nav=item">Home</li>
<li class="nav=item">About</li>
<li class="nav=item">Menu</li>
<li class="nav=item">Testimonials</li>
<li class="nav=item">Team</li>
<li class="nav=item">Contact</li>
</ul>
</nav>
CSS
.header .nav-toggler{
height: 40px;
width: 44px;
margin-right: 15px;
cursor: pointer;
border: none;
background-color: transparent;
display: flex;
align-items: center;
justify-content: center;
}
.header .nav-toggler.active{
position: absolute;
right: 0;
z-index: 1;
}
.header .nav{
position: fixed;
right: 0;
top: 0;
height: 100%;
width: 280px;
background-color: var(--main-color);
box-shadow: var(--shadow);
overflow-y: auto;
padding: 80px 0 40px;
transform: transform 0.5s ease;
transform: translateX(100%);
}
.header .nav .open{
transform: translateX(0%);
}
JavaScript
const navToggler = document.querySelector(".nav-toggler");
navToggler.addEventListener("click", toggleNav);
function toggleNav(){
navToggler.classList.toggle(".active");
document.querySelector(".nav").classList.toggle(".open");
}

The first issue you have is that you need to remove the . (period) from your class references (toggle(".active")). Making your toggleNav method like:
function toggleNav(){
navToggler.classList.toggle("active");
document.querySelector(".nav").classList.toggle("open");
}
Also, in your css you reference an object with a .header class that does not exist. So you would need to wrap your entire html with:
<div class='header'>
... [YOUR HTML CODE]
</div>
Also, in your css your declaration:
.header .nav .open
Should be:
.header .nav.open
You need a bit of css work for it to function smoothly but this should point you in the right direction.

There are some JS and css issues in your code. check following code.
const navToggler = document.querySelector(".nav-toggler");
navToggler.addEventListener("click", toggleNav);
function toggleNav(){
navToggler.classList.toggle("active");
document.querySelector(".nav").classList.toggle("open");
}
.header .nav-toggler{
height: 40px;
width: 44px;
margin-right: 15px;
cursor: pointer;
border: none;
background-color: transparent;
display: flex;
align-items: center;
justify-content: center;
background: red;
}
.header .nav{
position: fixed;
right: 0;
top: 0;
height: 100%;
width: 280px;
background-color: var(--main-color);
box-shadow: var(--shadow);
overflow-y: auto;
padding: 80px 0 40px;
transition: transform 0.5s ease;
transform: translateX(100%);
}
.header .nav.open{
transform: translateX(0%);
}
<div class="header">
<button type="button" class="nav-toggler">
<span></span>
</button>
<!--Navbar-->
<nav class="nav">
<ul>
<li class="nav=item">Home</li>
<li class="nav=item">About</li>
<li class="nav=item">Menu</li>
<li class="nav=item">Testimonials</li>
<li class="nav=item">Team</li>
<li class="nav=item">Contact</li>
</ul>
</nav>
</div>

const navToggler = document.querySelector(".nav-toggler");
navToggler.addEventListener("click", toggleNav);
function toggleNav(){
navToggler.classList.toggle("active");
document.querySelector("nav").classList.toggle("open");
}
.header .nav-toggler{
height: 40px;
width: 44px;
margin-right: 15px;
cursor: pointer;
border: none;
background-color: transparent;
display: flex;
align-items: center;
justify-content: center;
}
.header .nav-toggler.active{
position: absolute;
right: 0;
z-index: 1;
}
.header .nav{
position: fixed;
right: 0;
top: 0;
height: 100%;
width: 280px;
background-color: var(--main-color);
box-shadow: var(--shadow);
overflow-y: auto;
padding: 80px 0 40px;
transform: transform 0.5s ease;
transform: translateX(100%);
}
.header .nav.open{
transform: translateX(0%);
}
<div class="header">
<button type="button" class="nav-toggler active">
<span>button</span>
</button>
<!--Navbar-->
<nav class="nav open">
<ul>
<li class="nav=item">Home</li>
<li class="nav=item">About</li>
<li class="nav=item">Menu</li>
<li class="nav=item">Testimonials</li>
<li class="nav=item">Team</li>
<li class="nav=item">Contact</li>
</ul>
</nav>
</div>
Problems in code
classList.toggle(".active"); remove . in string like classList.toggle("active");
add <div> main div in side code class is .header
remove space in between .header .nav .open like- .header .nav.open in css

Related

VueJs: Responsive NavBar - 'ToggleButton' does not show elements?

I'm building a single page application in VueJs, and to this i would like to add a responsive NavBar.
Whatever i try and do, it simply dosen't work.
I've tried many solution, the closest i get to my goal is the following:
HTML
<template>
<header>
<nav class="navbar">
<img style="width: 100px; border-radius: 50%;" src="../.." alt="Name here">
Name
<ul class="nav-menu">
<li class="nav-item custom-header-li">
<RouterLink class="custom-header-menu-text" to="#">1</RouterLink>
</li>
<li class="nav-item custom-header-li">
<RouterLink class="custom-header-menu-text" to="#">2</RouterLink>
</li>
<li class="nav-item custom-header-li">
<RouterLink class="custom-header-menu-text" to="#">3</RouterLink>
</li>
<li class="nav-item custom-header-li">
<RouterLink class="custom-header-menu-text" to="#">4</RouterLink>
</li>
<li class="nav-item custom-header-li">
<RouterLink class="custom-header-menu-text" to="#">5</RouterLink>
</li>
</ul>
<div class="hamburger">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</div>
</nav>
</header>
</template>
CSS
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
header {
background-color: #ffffff;
}
.custom-header-li {
list-style: none;
}
.navbar {
min-height: 70px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
}
.nav-menu {
display: flex;
justify-content: space-between;
align-items: center;
gap: 60px;
}
.nav-branding {
text-align: center;
}
.nav-link {
transition: 0.7s ease;
}
.nav-link:hover {
border-bottom: 3px solid #080808;
font-size: 20px;
transition: 0.5s;
color: #080808;
}
.hamburger {
display: none;
cursor: pointer;
}
.bar {
display: block;
width: 25px;
height: 3px;
margin: 5px auto;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
background-color: #080808;
}
#media(max-width:767px) {
.hamburger {
display: block;
}
.hamburger.active .bar:nth-child(2) {
opacity: 0;
}
.hamburger.active .bar:nth-child(1) {
transform: translateY(8px) rotate(45deg);
}
.hamburger.active .bar:nth-child(3) {
transform: translateY(-8px) rotate(-45deg);
}
.nav-menu {
position: fixed;
left: -100%;
top: 70px;
gap: 0;
flex-direction: column;
background-color: #080808;
width: 100%;
text-align: center;
transition: 0.3s;
}
.nav-item {
margin: 16px 0;
}
.nav-menu:active {
left: 0;
}
}
</style>
JS
<script>
export default {
setup() {
window.addEventListener("click", function(event){
const hamburger = document.querySelector(".hamburger");
const navMenu = document.querySelector(".nav-menu");
hamburger.classList.toggle("active");
navMenu.classList.toggle("active");
})
}
}
</script>
I tried printing, and see that the class changes to 'active' and it does - even the icon changes view, but the list dosen't show up ?
Can anyone see what's wrong with the code?
I've also tried this solution for Vue: https://codepen.io/raphaelbensimon/pen/VGbLed (Excluded the loader/spinner)
Here the problem is that the 'ToggleIcon' just dosen't show up, at all!
Can someone please help? :D
Just make a change in your css to:
.nav-menu.active {
left: 0;
}
It's work. Testing

FadeInLeft effect when changing content

window.addEventListener('scroll', () => {
let scrollDistance = window.scrollY;
if (window.innerWidth > 768) {
document.querySelectorAll('.section1').forEach((el, i) => {
if (el.offsetTop - document.querySelector('.nav').clientHeight <= scrollDistance) {
document.querySelectorAll('.nav a').forEach((el) => {
if (el.classList.contains('active')) {
el.classList.remove('active');
}
});
document.querySelectorAll('.nav li')[i].querySelector('a').classList.add('active');
}
});
}
});
body {
background: gray;
padding: 100px;
}
.block-2 {
display: flex;
flex-direction: row;
background: white;
width: 100%;
padding: 50px;
height: auto;
}
.section-left {
position: sticky;
top: 10px;
height: 300px;
/* background: gray; */
width: 100%;
}
.section-right {
background: blue;
width: 100%;
}
.wrap {
margin: 10px;
background: red;
}
.content {
height: 500px;
}
.footer {
width: 100%;
height: 700px;
background: red;
}
.nav {
position: relative;
left: 0;
top: 0;
width: 100%;
background-color: white;
/* padding: 20px;
*/
}
.nav ul {
display: flex;
list-style-type: none;
flex-direction: column;
padding: 0;
}
.nav a {
display: flex !important;
text-decoration: none;
color: black !important;
display: inline-block;
/* margin-right: 25px !important;
*/
}
#media screen and (max-width: 1024px) {}
.subtitle {
opacity: 0;
}
.active {
opacity: 1;
}
.content1 {
position: absolute;
background-color: red;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content2 {
position: absolute;
background-color: gray;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content3 {
position: absolute;
background-color: green;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content4 {
position: absolute;
background-color: blue;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
<body>
<div class="block-2">
<div class="section-left">
<nav class="nav">
<ul>
<li><a href="" class="active subtitle">
<div class="content1">
<h1>O1</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content2">
<h1>O2</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content3">
<h1>O3</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content4">
<h1>O4</h1>
</div>
</a></li>
</ul>
</nav>
</div>
<div class="section-right">
<div class="section1 wrap">
<div class="content">asdf</div>
</div>
<div class="wrap section1 ">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
</div>
</div>
<div class="footer"></div>
</body>
How can I get the FadeInLeft effect when changing content from .opacity=0 to .opacity=1 on the left side.
I tried to solve this problem with the given script, but it did not work for me.
P.S. See this layout in fullscreen.
Here is a very ruff first draft
Since you already have the .active class being added to your .subtitle class to change opacity, you can just tack on CSS Animation to those classes.
In my example I have .subtitle > div set to right: 100%; and .active > div set to right: 0%; with a transition: 300ms;
Which will animate the block from the left side of the screen over to the right side in 300ms. You can play around with this until you get the animation where you'd like.
Here's a great article from MDN with more information about Using CSS Transitions
CSS transitions provide a way to control animation speed when changing CSS properties. Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time. For example, if you change the color of an element from white to black, usually the change is instantaneous. With CSS transitions enabled, changes occur at time intervals that follow an acceleration curve, all of which can be customized.
Examples
div {
transition: <property> <duration> <timing-function> <delay>;
}
#delay {
font-size: 14px;
transition-property: font-size;
transition-duration: 4s;
transition-delay: 2s;
}
#delay:hover {
font-size: 36px;
}
.box {
border-style: solid;
border-width: 1px;
display: block;
width: 100px;
height: 100px;
background-color: #0000FF;
transition: width 2s, height 2s, background-color 2s, transform 2s;
}
.box:hover {
background-color: #FFCCCC;
width: 200px;
height: 200px;
transform: rotate(180deg);
}
window.addEventListener('scroll', () => {
let scrollDistance = window.scrollY;
if (window.innerWidth > 768) {
document.querySelectorAll('.section1').forEach((el, i) => {
if (el.offsetTop - document.querySelector('.nav').clientHeight <= scrollDistance) {
document.querySelectorAll('.nav a').forEach((el) => {
if (el.classList.contains('active')) {
el.classList.remove('active');
}
});
document.querySelectorAll('.nav li')[i].querySelector('a').classList.add('active');
}
});
}
});
body {
background: gray;
padding: 100px;
}
.block-2 {
display: flex;
flex-direction: row;
background: white;
width: 100%;
padding: 50px;
height: auto;
}
.section-left {
position: sticky;
top: 10px;
height: 300px;
/* background: gray; */
width: 100%;
}
.section-right {
background: blue;
width: 100%;
}
.wrap {
margin: 10px;
background: red;
}
.content {
height: 500px;
}
.footer {
width: 100%;
height: 700px;
background: red;
}
.nav {
position: relative;
left: 0;
top: 0;
width: 100%;
background-color: white;
/* padding: 20px;
*/
}
.nav ul {
display: flex;
list-style-type: none;
flex-direction: column;
padding: 0;
}
.nav a {
display: flex !important;
text-decoration: none;
color: black !important;
display: inline-block;
/* margin-right: 25px !important;
*/
}
#media screen and (max-width: 1024px) {}
.subtitle {
opacity: 0;
transition:300ms;
}
.subtitle > div {
transition:300ms;
right:100%;
}
.subtitle > div h1 {
opacity:0;
position:relative;
top:2em;
transition:300ms;
transition-delay:1s;
}
.active {
opacity: 1;
}
.active > div {
right:0;
}
.active > div h1 {
opacity:1;
top: 0;
}
.content1 {
position: absolute;
background-color: red;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content2 {
position: absolute;
background-color: gray;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content3 {
position: absolute;
background-color: green;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content4 {
position: absolute;
background-color: blue;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
<body>
<div class="block-2">
<div class="section-left">
<nav class="nav">
<ul>
<li><a href="" class="active subtitle">
<div class="content1">
<h1>O1</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content2">
<h1>O2</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content3">
<h1>O3</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content4">
<h1>O4</h1>
</div>
</a></li>
</ul>
</nav>
</div>
<div class="section-right">
<div class="section1 wrap">
<div class="content">asdf</div>
</div>
<div class="wrap section1 ">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
</div>
</div>
<div class="footer"></div>
</body>

Javascript eventListener only working in some areas of the element

So i was building a burger menu responsive navbar. I finished up most of the working but i got stuck at one point. The problem is i have applied the javascript onClick event listener on the div .burger so that it changes the opacity of the .nav-container to 1. Up until to this point this works fine. The problem is this click event only works in some areas on the .burger. Like if clicked on of the lines in it or somewhere to the right. I can't seem to find the problem. Can someone help me with this? Thanks in advance.
Here is my code
function showNav() {
var nav = document.getElementById("nav");
nav.classList.add("show-nav");
}
* {
margin: 0px;
padding: 0;
box-sizing: border;
}
.container {
display: flex;
margin-top: 2%;
}
header {
position: relative;
z-index: 1;
}
.line1,
.line2,
.line3 {
width: 40px;
height: 8px;
background-color: black;
margin-top: 3px;
}
.nav-heading {
flex: 4;
margin-left: 5%;
}
.burger {
flex: 1;
margin-left: 40%;
background-color: red;
padding: 0;
width: auto;
}
.nav-container {
position: absolute;
width: 100%;
opacity: 0;
transition: .2s ease-in-out;
transform: translateY(-20%);
transform-origin: left;
ul {
display: flex;
flex-direction: column;
background-color: blue;
width: 100%;
align-items: center;
list-style-type: none;
li {
flex: 1;
padding: 15px;
}
}
}
.show-nav {
opacity: 1;
transform: translateY(20%);
}
<header>
<div class="container">
<div class="nav-heading">
<h1>Navbar</h1>
</div>
<div class="burger" onclick="showNav()">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</div>
<div class="nav-container" id="nav">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</header>
Just put z-index = 1 on .burger.
.burger {
flex: 1;
margin-left: 40%;
background-color: red;
padding: 0;
width: auto;
z-index: 1;
}
to bring your menu up front , you can add position:relative + z-index:1; to make sure it stands on top.
You also add the rule cursor: pointer; to show it is a clickable element :)
For the class you add, you could use classList . toggle() , so it shows/hides alternatively.
example
function showNav() {
var nav = document.getElementById("nav");
nav.classList.toggle("show-nav");
}
* {
margin: 0px;
padding: 0;
box-sizing: border;
}
.container {
display: flex;
margin-top: 2%;
}
header {
position: relative;
z-index: 1;
}
.line1,
.line2,
.line3 {
width: 40px;
height: 8px;
background-color: black;
margin-top: 3px;
}
.nav-heading {
flex: 4;
margin-left: 5%;
}
.burger {
flex: 1;
margin-left: 40%;
background-color: red;
padding: 0;
width: auto;
cursor: pointer;
position:relative;
z-index:1
}
.nav-container {
position: absolute;
width: 100%;
opacity: 0;
transition: .2s ease-in-out;
transform: translateY(-20%);
transform-origin: left;
}
ul {
display: flex;
flex-direction: column;
background-color: blue;
width: 100%;
align-items: center;
list-style-type: none;
}
li {
flex: 1;
padding: 15px;
}
li a {
color: black;
}
.show-nav {
opacity: 1;
transform: translateY(20%);
}
<header>
<div class="container">
<div class="nav-heading">
<h1>Navbar</h1>
</div>
<div class="burger" onclick="showNav()">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</div>
<div class="nav-container" id="nav">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</header>
Just change the width of
.nav-container {
width: 30%;
}
so it doesn't overlap the burger. In general your CSS structure is not good.

Javascript event listener overwrites another event listener

so I am trying to create a multilevel navigation for a mobile device and I am running into some issues. I am still learning javascript so please bare with me. Here is a link to the codepen:
https://codepen.io/maciekmat/pen/yLepYKq
So when you press the menu in the top right, a menu will open down. Then I would like to be able to go into sub categories. For example click Test Open, .active class will be assigned, and another menu slides in. Now I would like to have a go back button that essentially removes the .active class.
However what I think is happening, the event listener listens to the whole parent, and anywhere you click inside the subnavigation, it registers it as a click, and runs the .active class. When I click to go back, its like .active is removed and applied back instantly. Any help please?
I tried doing the event.currentEvent !== event.target if statement but had no luck
const nav = document.getElementById('menuIcon')
const dropdown = document.getElementById('menuDropdown')
nav.addEventListener('click', function() {
dropdown.classList.toggle('nav-is-toggled')
});
const grabNavLinks = document.querySelectorAll('.sub-nav-link');
const grabBackLinks = document.querySelectorAll('.nav-link.back');
const subNavLinks = Array.from(grabNavLinks);
const backLinks = Array.from(grabBackLinks);
for (let i = 0; i < subNavLinks.length; i++) {
subNavLinks[i].addEventListener("click", function() {
this.querySelector('.sub-nav').classList.add('active');
});
}
for (let i = 0; i < backLinks.length; i++) {
backLinks[i].addEventListener("click", function() {
document.querySelector('.sub-nav').classList.remove('active');
});
}
#import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght#300;400;600;700&display=swap");
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: "Open sans", sans-serif;
background: #F9F9F9;
box-sizing: border-box;
}
a, p, h1, h2, h3 {
margin: 0;
padding: 0;
text-decoration: none;
}
ul, li {
padding: 0;
margin: 0;
}
header {
background: white;
padding: 24px 30px;
display: flex;
flex-direction: column;
z-index: 10;
position: relative;
}
.top-nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.top-nav .logo {
background: url("images/tcb-logo-brand.svg") no-repeat;
width: 150px;
height: 50px;
background-size: contain;
background-position: center;
}
.top-nav .navigation {
display: flex;
justify-content: space-between;
width: 132px;
height: 26px;
}
.top-nav .navigation .nav-item {
width: 23px;
height: 26px;
margin-left: 10px;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.top-nav .navigation .nav-item.menu {
background-image: url("images/menu-icon.svg");
}
.top-nav .navigation .nav-item.notification {
background-image: url("images/bell-icon.svg");
}
.top-nav .navigation .nav-item.my-account {
background-image: url("images/acc-icon.svg");
}
.search {
margin-top: 16px;
}
.search input[type=search] {
outline: none;
border: none;
background: #F6F6F6;
width: 100%;
height: 50px;
font-size: 16px;
padding: 10px 0 10px 20px;
background-image: url("images/search-icon.svg");
background-repeat: no-repeat;
background-position: right 15px top 50%;
}
.search input[type=search]::placeholder {
color: #B7B7B7;
}
span.nav-title {
display: none;
}
nav.main-nav {
width: 100%;
background: #F6F6F6;
transform: translateY(-100%);
z-index: 0;
position: relative;
transition: all 0.3s ease-in-out;
position: absolute;
padding-bottom: 50px;
overflow: hidden;
}
nav.main-nav ul {
padding-top: 2px;
position: relative;
}
nav.main-nav li {
list-style: none;
}
nav.main-nav a {
color: #6D6D6D;
font-size: 16px;
width: 100%;
height: 100%;
display: block;
padding: 18px 30px;
border-bottom: 1px solid #E9E9E9;
}
nav.main-nav li.nav-link.arrow {
background: url("images/right-arrow.svg") no-repeat;
background-position: right 30px top 50%;
}
nav.main-nav ul.sub-nav {
background: #cecece;
width: 100%;
display: flex;
flex-direction: column;
transform: translateX(100%);
overflow: hidden;
visibility: hidden;
opacity: 0;
position: absolute;
top: 0;
left: 0;
transition: transform 0.2s ease;
}
.sub-nav-link > .sub-nav.active {
transform: translateX(0);
visibility: visible;
opacity: 1;
}
nav.nav-is-toggled {
position: static;
opacity: 1;
transform: translateY(0);
transition: all 0.3s ease-in-out;
}
<header>
<div class="top-nav">
<div class="logo"></div>
<div class="navigation">
<div id="menuIcon" class="nav-item menu">test</div>
<div class="nav-item notification"></div>
<div class="nav-item my-account"><span class="nav-title">My Account</span></div>
</div>
</div>
<div class="search">
<input type="search" name="search" id="search" placeholder="Search by store...">
</div>
</header>
<nav id="menuDropdown" class="main-nav">
<ul class="main-nav-ul">
<li class="nav-link">Test</li>
<li class="nav-link arrow sub-nav-link">Test Open
<ul class="sub-nav">
<li class="nav-link back">Go Back</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
</ul>
</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
<li class="nav-link arrow sub-nav-link">Test Open
<ul class="sub-nav">
<li class="nav-link back">Go Back</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
</ul>
</li>
<li class="nav-link">Test</li>
</ul>
</nav>
<script src="navigation.js"></script>
Go read on event bubbling and how it bubbles through the DOM tree. However due to the way it passes from parent to child (that's it bubbles down the tree) you should call event.stopPropagation(); So that the previous event doesnt bubble into the backLinks event listener.
This is what you should do
for (let i = 0; i < backLinks.length; i++) {
backLinks[i].addEventListener("click", function(event) {
event.stopPropagation();
document.querySelector('.sub-nav').classList.remove('active');
});
}

Dropdown pushing logo downwards

I'm doing a custom drop-down navigation but when it toggles the logo, in this codepen represented by the blue div, goes to the bottom of the navigation. I've been trying to work around this for a while now and would appreciate any help.
Here is my code:
HTML
<div class='container-fluid nav'>
<div class='container'>
<div class = 'nav__btn--toggle u-inlineBlock u-center' onclick="animateNavbarToggle(this); toggleDropdown();">
<div class = 'nav__btn bar1'></div>
<div class = 'nav__btn bar2'></div>
<div class = 'nav__btn bar3'></div>
</div>
<ul class = "nav__dropdown">
<li>Home</li>
<li>About</li>
<li>Work</li>
<li>Blog</li>
<li>Contact</li>
</ul>
<div class='nav__brand u-inlineBlock'>
logo
</div>
</div>
</div>
CSS
.nav__dropdown {
padding-left: 0;
margin-top: 75px;
list-style: none;
text-align: center;
box-sizing: border-box;
display: none;
}
.nav__dropdown li {
font-size: 20px;
padding: 25px;
width: 40%;
background: white;
border-bottom: 1px solid black;
}
.nav__dropdown li:last-child{
border-bottom: none;
}
.nav__dropdown li:hover{
background: black;
color: seashell
}
.u-inlineBlock {
display: inline-block;
}
JS
function toggleDropdown(x) {
$('.nav__dropdown').slideToggle(500);
}
After this, I'll try to add a sub menu on the right side, so if you could point me in the right path for that as well that would be great
(Notice that this is just a bonus for me, I don't care if you don't help me with that so don't downvote for being too broad or something like that. I also saw some similar questions but they did not help)
Thanks in advance!
Just move the logo before the ul, and remove the margin-top from the ul. And if you want the toggle button and submenu to be flush with the white header, remove .nav { height: 75px; }
function animateNavbarToggle(x) {
x.classList.toggle("toggled");
}
function toggleDropdown(x) {
$('.nav__dropdown').slideToggle(500);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<style>
body {
background-color: pink;
height: 2000px;
}
/*------------------------------------*\
#NAVIGATION
\*------------------------------------*/
.nav {
background-color: white;
height: 75px;
}
.nav__brand {
height: 68px;
width: 227px;
background-color: lightblue;
text-align: center;
}
/**
* Navigation dropdown button
*/
.nav__btn {
width: 22PX;
height: 3px;
background-color: black;
margin: 4px 0;
}
.nav__btn--toggle {
cursor: pointer;
}
.bar1, .bar2, .bar3 {
width: 22PX;
height: 3px;
background-color: coral;
margin: 4px 0;
transition: 0.4s;
}
/* Rotate first bar */
.toggled .bar1 {
-webkit-transform: rotate(-45deg) translate(-5px, 5px);
transform: rotate(-45deg) translate(-5px, 5px);
}
/* Fade out the second bar */
.toggled .bar2 {
opacity: 0;
}
/* Rotate last bar */
.toggled .bar3 {
-webkit-transform: rotate(45deg) translate(-4px, -4px);
transform: rotate(45deg) translate(-4px, -6px);
}
/**
* Navigation Dropdown
*/
.nav__dropdown {
padding-left: 0;
list-style: none;
text-align: center;
box-sizing: border-box;
display: none;
}
.nav__dropdown li {
font-size: 20px;
padding: 25px;
width: 40%;
background: white;
border-bottom: 1px solid black;
}
.nav__dropdown li:last-child {
border-bottom: none;
}
.nav__dropdown li:hover {
background: black;
color: seashell;
}
/*------------------------------------*\
#UTILITIES
\*------------------------------------*/
.u-inlineBlock {
display: inline-block;
}
.u-center {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
</style>
<div class='container-fluid nav'>
<div class='container'>
<div class='nav__btn--toggle u-inlineBlock u-center' onclick="animateNavbarToggle(this); toggleDropdown();">
<div class='nav__btn bar1'></div>
<div class='nav__btn bar2'></div>
<div class='nav__btn bar3'></div>
</div>
<div class='nav__brand u-inlineBlock'>
logo
</div>
<ul class="nav__dropdown">
<li>Home</li>
<li>About</li>
<li>Work</li>
<li>Blog</li>
<li>Contact</li>
</ul>
</div>
</div>
try adding position: fixed to your nav__dropdown CSS
.nav__dropdown {
padding-left: 0;
margin-top: 75px;
list-style: none;
text-align: center;
box-sizing: border-box;
display: none;
position: fixed;
}
Position fixed essentially removes the content from the flow of the document window, which makes it not cause any interactions with your logo.
More on position fixed here

Categories