How do I close the dropdown button in Vanilla JS? I currently have a method to open the dropdown button but no way in which the close the button. I would like to keep the for loop in place but am unsure as to how to achieve the close. What is the proper way to handle the problem? Help would be appreciated. HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script
src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/36947df53d.js" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div >
<p id="logo">Logo</p>
<button id="btn"><i ></i></button>
</div>
<nav class ="">
<ul class ="">
<li><a href="#" >Link 1</a></li>
<li><a href="#" >Link 2</a></li>
<li><a href="#" >Link 3</a></li>
</ul>
</nav>
<script src="script.js"></script>
</body>
</html>
JS
let btnn = document.getElementById("btn");
btnn.addEventListener("click", changeBtn);
function changeBtn() {
let links = document.getElementsByClassName('link');
for (let i = 0; i < links.length; i ) {
document.getElementsByClassName('link')[i].style.display = "block";
}
}
CSS
body {
height: 100vh;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.logo {
display: block;
text-align: left;
background: red;
height: 10vh;
}
.logo #logo {
display: inline;
line-height: 10vh;
font-size: 3em;
margin-left: 0.8em;
}
button#btn {
display: inline;
float: right;
margin-right: 2em;
line-height: 10vh;
margin-top: 0;
margin-bottom: 0;
border: none;
background-color: red;
padding: 0;
}
nav {
display: block;
background-color: black;
width: 100vw;
}
nav ul {
display: block;
list-style-type: none;
margin: 0;
padding-left: 0;
}
nav ul li {
text-align: center;
}
.link {
display: none;
color: white;
font-size: 2.4em;
background-color: blue;
text-decoration: none;
width: 100vw;
height: 7vh;
line-height: 7vh;
border-bottom: 2px solid black;
text-align: center;
}
CodePudding user response:
You just need to add one function for the close button in javascript where the display is set to none on clicking the button again. You can do the same by clicking anywhere by window object.
Below is the code after the correction of the javascript part for closing the menu after clicking the button again. Hope you understand well. Please upvote if you like.
let btnn = document.getElementById("btn");
btnn.addEventListener("click", changeBtn);
function changeBtn() {
let links = document.getElementsByClassName('link');
for (let i = 0; i < links.length; i ) {
document.getElementsByClassName('link')[i].style.display = "block";
}
// close the menu after clicking again
btnn.removeEventListener("click", changeBtn);
btnn.addEventListener("click", closeBtn);
}
function closeBtn() {
let links = document.getElementsByClassName('link');
for (let i = 0; i < links.length; i ) {
document.getElementsByClassName('link')[i].style.display = "none";
}
// open the menu after clicking again
btnn.removeEventListener("click", closeBtn);
btnn.addEventListener("click", changeBtn);
}
body {
height: 100vh;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.logo {
display: block;
text-align: left;
background: red;
height: 10vh;
}
.logo #logo {
display: inline;
line-height: 10vh;
font-size: 3em;
margin-left: 0.8em;
}
button#btn {
display: inline;
float: right;
margin-right: 2em;
line-height: 10vh;
margin-top: 0;
margin-bottom: 0;
border: none;
background-color: red;
padding: 0;
}
nav {
display: block;
background-color: black;
width: 100vw;
}
nav ul {
display: block;
list-style-type: none;
margin: 0;
padding-left: 0;
}
nav ul li {
text-align: center;
}
.link {
display: none;
color: white;
font-size: 2.4em;
background-color: blue;
text-decoration: none;
width: 100vw;
height: 7vh;
line-height: 7vh;
border-bottom: 2px solid black;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script
src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
crossorigin="anonymous"
></script>
<script
src="https://kit.fontawesome.com/36947df53d.js"
crossorigin="anonymous"
></script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div >
<p id="logo">Logo</p>
<button id="btn"><i ></i></button>
</div>
<nav >
<ul >
<li><a href="#" >Link 1</a></li>
<li><a href="#" >Link 2</a></li>
<li><a href="#" >Link 3</a></li>
</ul>
</nav>
<script src="script.js"></script>
</body>
</html>
CodePudding user response:
You can use a simple classList.toggle
function in JS by assigning a base class and then a "visible" class and just toggle between the two on click. See: https://www.w3schools.com/howto/howto_js_toggle_class.asp
Edit: added in the forEach
just in case you wanted multiple buttons
let btnn = document.querySelectorAll(".btn");
btnn.forEach(btnn => btnn.addEventListener('click', function() {
let links = document.getElementById('links');
links.classList.toggle("visible");
}))
body {
height: 100vh;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.logo {
display: block;
text-align: left;
background: red;
height: 10vh;
}
.logo #logo {
display: inline;
line-height: 10vh;
font-size: 3em;
margin-left: 0.8em;
}
button#btn {
display: inline;
float: right;
margin-right: 2em;
line-height: 10vh;
margin-top: 0;
margin-bottom: 0;
border: none;
background-color: red;
padding: 0;
}
nav {
display: block;
background-color: black;
width: 100vw;
}
nav ul {
display: block;
list-style-type: none;
margin: 0;
padding-left: 0;
}
nav ul li {
text-align: center;
}
.link {
display: block;
color: white;
font-size: 2.4em;
background-color: blue;
text-decoration: none;
width: 100vw;
height: 7vh;
line-height: 7vh;
border-bottom: 2px solid black;
text-align: center;
}
.links {
display: none;
}
.links.visible {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/36947df53d.js" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div >
<p id="logo">Logo</p>
<button id="btn"><i ></i></button>
</div>
<nav >
<ul id="links">
<li><a href="#" >Link 1</a></li>
<li><a href="#" >Link 2</a></li>
<li><a href="#" >Link 3</a></li>
</ul>
</nav>
<script src="script.js"></script>
</body>
</html>
CodePudding user response:
A more simple approach would be to add a class to the nav element and then toggle the visibility of nav element using the changeBtn
function
I have highlighted the changes to the code using comments
HTML:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script
src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/36947df53d.js" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div >
<p id="logo">Logo</p>
<button id="btn"><i ></i></button>
</div>
<nav id="main_nav" class =""> <!-- added id to nav element -->
<ul class ="">
<li><a href="#" >Link 1</a></li>
<li><a href="#" >Link 2</a></li>
<li><a href="#" >Link 3</a></li>
</ul>
</nav>
<script src="script.js"></script>
</body>
</html>
CSS:
body {
height: 100vh;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.logo {
display: block;
text-align: left;
background: red;
height: 10vh;
}
.logo #logo {
display: inline;
line-height: 10vh;
font-size: 3em;
margin-left: 0.8em;
}
button#btn {
display: inline;
float: right;
margin-right: 2em;
line-height: 10vh;
margin-top: 0;
margin-bottom: 0;
border: none;
background-color: red;
padding: 0;
}
nav {
display: none;
background-color: black;
width: 100vw;
}
nav ul {
display: block;
list-style-type: none;
margin: 0;
padding-left: 0;
}
nav ul li {
text-align: center;
}
.link {
display: block; /* Changed display: none to display: block */
color: white;
font-size: 2.4em;
background-color: blue;
text-decoration: none;
width: 100vw;
height: 7vh;
line-height: 7vh;
border-bottom: 2px solid black;
text-align: center;
}
Js:
let btnn = document.getElementById("btn");
btnn.addEventListener("click", changeBtn);
function changeBtn() { //changes to function
let main_nav = document.getElementById("main_nav");
if (main_nav.classList.contains("nav_active")) {
//when element has nav_active class, hide the nav element and remove
//the "nav-active" class
main_nav.style.display = "none";
main_nav.classList.remove("nav_active");
} else {
//when element doesn't have nav_active class, show the nav element
//and add the "nav-active" class
main_nav.style.display = "block";
main_nav.classList.add("nav_active");
}
}