I'm new to JavaScript and I've ran into a problem: I've built a dropdown menu/navbar in my HTML page. When you click a button, it opens up like it should, but I'm struggling with closing it. It's supposed to close when you click the button again, but I can't do that for some reason.
My method was to assign a class btn
and id disabled-btn
to a div. After clicking and opening the dropdown, button is supposed to have a new id of enabled-btn
, which is should be selected so I could reverse the process.
I understood via debugging that you can't query select an element if it's not on the page yet, but I haven't managed to bypass it anyhow.
This is one of the variants of code that I tried.
const disabledButton = document.querySelector('#disabled-btn')
const navbar = document.querySelector('.my_navbar')
const enabledButton = document.querySelector('#enabled-btn')
const button = document.querySelector('.btn')
disabledButton.onclick = () => {
navbar.style.transform = 'translate(0%, 0%)'
disabledButton.style.rotate = '90deg'
disabledButton.setAttribute('id', 'enabled-btn')
if (button === enabledButton) {
enabledButton.onclick = () => {
navbar.style.transform = 'translate (-100%, 0%)'
enabledButton.style.rotate = '0deg'
enabledButton.setAttribute('id', 'disabled-btn')
}
}
}
The HTML of a button and navbar:
<div id="disabled-btn">
<svg ...some svg here...></svg>
</div>
<nav >
<div ><a href="#">GALLERY</a></div>
<div ><a href="#">PRESETS</a></div>
<div ><a href="#">ABOUT</a></div>
<div ><a href="#">BOOKING</a></div>
</nav>
CodePudding user response:
Don't change ID's. They are unique identifiers and thus not meant to change. Instead I recommend using attributes. Just make sure it doesn't exist as an attribute already. When in doubt, add data-attributename
.
You will need to set event listeners to each item and deal with the logic inside of it. Here is an example with some comments on what is going on. I am not sure what you are trying to do styling wise, but I recommend just adding and removing classes, and deal with styles inside of CSS. This will make it conceptually more separate and easier to understand.
Let me know if this helps on what you are trying to achieve.
// Getting all the nav items in an a 'nodelist'
const navItems = document.querySelectorAll('.navbar .nav-item')
// Adding an event listener to each nav item
navItems.forEach( item => {
item.addEventListener('click', () => {
// check if item has 'active' attribute
if (item.hasAttribute('active')) {
// remove if it does
item.removeAttribute('active')
} else {
// otherwise add it
item.setAttribute('active', '')
}
})
})
.navbar a {
text-decoration: none;
color: black;
}
.nav-item[active] a {
text-decoration: underline;
color: blue;
}
<nav >
<div active>
<a href="#">GALLERY</a>
</div>
<div >
<a href="#">PRESETS</a></div>
<div >
<a href="#">ABOUT</a>
</div>
<div >
<a href="#">BOOKING</a>
</div>
</nav>
CodePudding user response:
css:you dont have to make seperate buttons for enable and disable.
here i gave some css to .my_navbar
and seperate css when it has active class with it.my_navbar.active
..
js:getting both nav and btn as usual with querySelector
the i am putting eventListerner
of typeclick
on disabledButton
& inside that function i am toggling
the active
on the navbar
.
hope it helped
/*const disabledButton = document.querySelector('#disabled-btn')
const navbar = document.querySelector('.my_navbar')
const enabledButton = document.querySelector('#enabled-btn')
const button = document.querySelector('.btn')
disabledButton.onclick = () => {
navbar.style.transform = 'translate(0%, 0%)'
disabledButton.style.rotate = '90deg'
disabledButton.setAttribute('id', 'enabled-btn')
if (button === enabledButton) {
enabledButton.onclick = () => {
navbar.style.transform = 'translate (-100%, 0%)'
enabledButton.style.rotate = '0deg'
enabledButton.setAttribute('id', 'disabled-btn')
}
}
}*/
const disabledButton = document.querySelector('#disabled-btn');
const navbar = document.querySelector('.my_navbar');
disabledButton.addEventListener("click", () => {
navbar.classList.toggle("active")
})
.my_navbar {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
padding: 0px;
gap: 10px;
background-color: gray;
height: 0;
overflow: hidden;
transition: all 0.25s ease-in-out;
}
.my_navbar.active {
padding: 20px;
height: 190px;
}
.my_navbar-nav {
width: 90%;
padding: 10px 30px;
background-color: lightgray;
}
.my_navbar-nav>a {
color: white;
text-decoration: none;
}
<div id="disabled-btn">
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40"
viewBox="0 0 24 24" stroke-width="1.5" stroke="#000000" fill="none" stroke- linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<line x1="4" y1="6" x2="20" y2="6" />
<line x1="4" y1="12" x2="20" y2="12" />
<line x1="4" y1="18" x2="20" y2="18" />
</svg>
</div>
<nav >
<div ><a href="#">GALLERY</a></div>
<div ><a href="#">PRESETS</a></div>
<div ><a href="#">ABOUT</a></div>
<div ><a href="#">BOOKING</a></div>
</nav>