When to use "toggle()" method instead of "add()" and "remove()" methods in Javascript
Table of contents
Introduction
According to MDN, the toggle()
method removes an existing token from the list and returns false
. If the token doesn't exist it's added and the function returns true.
In simpler terms, toggle allows you to alternate between two use cases with just a single line of code.
Before we proceed, this article doesn't cover the basics of javascript. It assumes you have a functional knowledge of javascript.
Attached below are the HTML and CSS markup if you want to follow along
Html markup
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
src="your font-awesome link"
crossorigin="anonymous"
></script>
<link rel="stylesheet" href="style.css" />
<script src="/app.js" defer></script>
<title>On Toggling</title>
</head>
<body>
<!-- Header -->
<header class="header">
<div class="header-name">Using toggling</div>
<div class="header-portfolio">
<ul>
<li><a href="#My_projects">Projects</a></li>
<li>
<a href="https://github.com/kodervine" target="_blank">GitHub</a>
</li>
<li>
<a
href="#"
target="_blank"
>LinkedIn</a
>
</li>
</ul>
<button class="button">
<a href="mailto:kodervine@gmail.com"
>Contact Me</a
>
</button>
</div>
<div class="navbar-menu-icon active">
<i class="fa-solid fa-bars"></i>
</div>
<div class="navbar-delete-icon"><i class="fa-solid fa-x"></i></div>
</header>
<!-- Mobile navbar -->
<section class="mobile-navbar-container">
<ul class="mobile-navbar">
<li><a href="#My_projects">Projects</a></li></li>
<li>
<a href="mailto:kodervine@gmail.com"
>Contact</a
>
</li>
<li>
<a href="https://github.com/kodervine" target="_blank">Github</a>
</li>
<li>
<a
href="#"
target="_blank"
>LinkedIn</a
>
</li>
</ul>
</section>
<script src="/app.js"></script>
</body>
</html>
CSS markup
@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Lato", Helvetica, sans-serif;
color: var(--primary-black-color);
}
/* Header */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 85px;
background-color: white;
box-shadow: 0 5px 5px rgba(221, 218, 218, 0.75);
position: sticky;
top: 0vh;
z-index: 1000;
}
.header-name {
font-size: 20px;
text-transform: uppercase;
}
.header-portfolio {
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
}
.header ul {
display: flex;
gap: 50px;
font-weight: bold;
font-size: 16px;
}
.header li {
list-style: none;
}
.header li:hover {
transform: translateY(-1px);
transition: 0.5s ease;
}
.header a {
text-decoration: none;
color: var(--primary-black-color);
}
.header a:hover {
color: var(--primary-blue-color);
}
.header .button {
border: 2px solid var(--primary-black-color);
padding: 10px 20px;
align-self: center;
background-color: transparent;
border-radius: 5px;
cursor: pointer;
font-size: 15px;
font-weight: bold;
}
.header .button:hover {
transform: scale(1.1);
transition: 1s ease;
}
/* Mobile navbar */
.mobile-navbar-container {
display: none;
}
.navbar-menu-icon {
display: none;
}
.navbar-delete-icon {
display: none;
}
/* Media queries */
@media (max-width: 768px) {
.header {
padding: 20px 40px 20px 30px;
}
.header .button {
display: none;
}
.header-portfolio {
display: none;
}
.mobile-navbar-container.active {
display: block;
}
.mobile-navbar {
height: 100vh;
background-color: white;
color: var(--darkest-blue);
overflow: hidden;
display: flex;
flex-direction: column;
gap: 20px;
padding: 0 0 0 2rem;
}
.mobile-navbar li {
padding: 10px;
list-style: none;
transform: 1s ease-in;
}
.mobile-navbar a {
color: var(--darkest-blue);
text-decoration: none;
}
.mobile-navbar a:hover {
border-bottom: 2px solid black;
}
/* Menu icons */
.navbar-menu-icon.active {
display: block;
cursor: pointer;
}
.navbar-delete-icon.active {
display: block;
cursor: pointer;
}
}
However, you should link your fontawesome kit to the HTML header.
Go here to get your font-awesome kit
Explaining the code structure
To explain the HTML and CSS markups to be used for the functionality, I created 2 navs
One for the large screen, with the class of header-portfolio
and one for mobile screen, mobile-navbar-container
In the css file, the section with the class of mobile-navbar-container
is set to hidden
on large screen
While the navbar with the class of header-portfolio
and the header button
is set to hidden
on small screen
However, notice that the css file contains a class of “active”
added to the “mobile-navbar-container”
, the navbar-menu-icon
and the navbar-delete-icon
on the media query
The active
class allows the display to be block on the small screen when we handle the functionality
Working on the Javascript file using add() and remove() methods
Let's say you want to create a responsive menu that hides and displays the navbars on the small screen.
Usually, your function would probably go like this 👇
const mobileNavbarContainer = document.querySelector(
".mobile-navbar-container"
);
const navbarMenuIcon = document.querySelector(".navbar-menu-icon");
const navbardeleteIcon = document.querySelector(".navbar-delete-icon");
navbarMenuIcon.addEventListener("click", () => {
mobileNavbarContainer.classList.add("active");
navbarMenuIcon.classList.remove("active");
navbardeleteIcon.classList.add("active");
});
navbardeleteIcon.addEventListener("click", () => {
mobileNavbarContainer.classList.remove("active");
navbarMenuIcon.classList.add("active");
navbardeleteIcon.classList.remove("active");
});
Explaining the add() and remove() methods
To quickly explain the code above -
I declared the mobileNavbarContainer
variable which becomes visible on the small screen.
The mobileNavbarContainer
is what contains the navbar list items for the mobile screen Add the picture showing the console
In the video below, Notice that when I click on the menu
icon, it gets hidden and the “X”
shows up in its place.
So, I accessed the font awesome for both the menu bar
icon and delete icon
and saved to different variables
const navbarMenuIcon = document.querySelector(".navbar-menu-icon");
const navbardeleteIcon = document.querySelector(".navbar-delete-icon");
Then added an event listener
to each of the icons.
When the navbarMenuIcon
is clicked,
We add the class
active
to themobileNavbarContainer
Then we remove the class of
active
to thenavbarMenuIcon
Finally, we add the class of
active
to thenavbardeleteIcon
When it’s the navbardeleteIcon
being clicked, we do the reverse for the add
and remove
methods.
navbarMenuIcon.addEventListener("click", () => {
mobileNavbarContainer.classList.add("active");
navbarMenuIcon.classList.remove("active");
navbardeleteIcon.classList.add("active");
});
navbardeleteIcon.addEventListener("click", () => {
mobileNavbarContainer.classList.remove("active");
navbarMenuIcon.classList.add("active");
navbardeleteIcon.classList.remove("active");
});
Now, if this is just a single usage, it is not a big deal.
But suppose you have different codes that need this kind of logic, your code becomes unnecessarily repetitive
Your code will end up being full of .add()
and .remove()
methods
Now, while this still gets the job done, we have other methods in Javascript to optimize our code while minimizing the lines of code used.
**That's where the toggle() method in Javascript comes in. **
You can check out mdn documentation here
Toggle() method in practice
Now, let us rework on the previous code sample but using toggle()
method instead
Remember that we have 2 icons that we want to add event listeners to.
The menuNavbarIcon
and the deleteNavbarIcon
So our target is this…
When we click on the menu bar icon for the menu (menuNavbarIcon)
, we want to hide the menu bar icon itself and display the “X” (deleteNavbarIcon)
STEP 1 - Selecting the icon variables
const navbarMenuIcon = document.querySelector(".navbar-menu-icon");
const navbardeleteIcon = document.querySelector(".navbar-delete-icon");
STEP 2 - Add Event Listeners to the icons
Then, we add the click
event listener type to the icon, you create a function
Previously, our function would have gone thus
/*iconPlaceHolder.addEventListener('click', function ( ) {
*The add and remove classlist goes here*
}*/
However, we simply need to declare the eventListeners for both icons
navbarMenuIcon.addEventListener("click", toggleMenu);
navbardeleteIcon.addEventListener("click", toggleMenu);
STEP 3 - Create function that handles the toggle() method
However, we are not going to manually declare the function for each of icons’
event listeners
Rather, we will create a function
that will handle the toggle()
for both use cases
So, let's just create the toggleMenu() function
function toggleMenu() {
mobileNavbarContainer.classList.toggle("active");
navbarMenuIcon.classList.toggle("active");
navbardeleteIcon.classList.toggle("active");
}
So, instead of adding and removing classLists
for each click, we just toggle between the active classes under the toggleMenu() function.
Then we called the function inside the eventListener for both the navbarMenuIcon
and navbardeleteIcon
Your javascript code should look like this with the toggle() method -
const mobileNavbarContainer = document.querySelector(
".mobile-navbar-container"
);
// declaring the variable for the event listeners
const navbarMenuIcon = document.querySelector(".navbar-menu-icon");
const navbardeleteIcon = document.querySelector(".navbar-delete-icon");
// The icons event listenrs for onclick
navbarMenuIcon.addEventListener("click", toggleMenu);
navbardeleteIcon.addEventListener("click", toggleMenu);
function toggleMenu() {
mobileNavbarContainer.classList.toggle("active");
navbarMenuIcon.classList.toggle("active");
navbardeleteIcon.classList.toggle("active");
}
And that's it folks.
Though this method is largely for syntactic sugar, it's still a great option to add to your code