I need to create a simple menu for my mobile site.
Desired functionality
When on mobile, we should see a hamburger icon and some text that says Site menu
.
The list of navigation links should be hidden at this stage.
When we tap on the hamburger icon, the navigation links will be revealed and displayed underneath. At the same time, the hamburger icon should be replaced by a close icon, represented by an “X”.
Tapping on the close icon, hides the navigation links again and replaces the close icon with the original hamburger icon.
Navigation element
The main navigation element for the site is a <nav>
containing the list of navigation links.
The nav
element has an id
attribute of navigation-menu
. The id
will
help us target this element with Javascript.
This element should be hidden from view when the page loads, so it has a
hidden
class on it.
<nav id="navigation-menu" class="hidden" />
<a href="...">...</a>
<a href="...">...</a>
<a href="...">...</a>
<a href="...">...</a>
</nav>
Open button, close button, and label
Buttons for opening and closing the navigation are plain svg
images.
In the sample code below, the buttons are img
elements with appropriate id
s
so they can be targeted later by Javascript.
The close menu button is hidden by default.
<img src="hamburger.svg" id="open-menu-btn" alt="Open Menu" />
<img src="close-btn.svg" id="close-menu-btn" alt="Close Menu" class="hidden" />
The menu label is a <span>
element with the text “Site menu” and an id
of
site-menu-label
.
<span id="site-menu-label">Site menu</span>
Now that we have all the html
elements in place, I can add the Javascript.
In my script I need to grab the four elements that make up the navigation
system: navigation element, open menu button, close menu button, and label, and
store a reference of them in four variables:
const openMenuBtn = document.querySelector("#open-menu-btn");
const navigationMenu = document.querySelector("#navigation-menu");
const closeMenuBtn = document.querySelector("#close-menu-btn");
const siteMenuLabel = document.querySelector("#site-menu-label");
The script functionality is very simple. All I need to do is hide the elements that are shown initially, and show the elements that are hidden, when an element is tapped by the user.
The element tapped is either the open menu button or the close menu button.
The way to show or hide an element is to add (or remove) a class named hidden
.
I can then write a function in my script that does just that.
The function accepts an array of the four elements that need to be shown or
hidden.
const elementList = [openMenuBtn, navigationMenu, closeMenuBtn, siteMenuLabel];
function toggleElements (elements) {
for (let element of elements) {
element.classList.toggle("hidden");
}
}
This function runs when a click
event is triggered.
The event listener is added to the document
and calls the toggleElements
function
only when we tap on one of the elements.
document.addEventListener("click", (event) => {
if (elementList.includes(event.target)) {
toggleElements(elementList);
}
})
Below is the full script.
<script>
const openMenuBtn = document.querySelector("#open-menu-btn");
const navigationMenu = document.querySelector("#navigation-menu");
const closeMenuBtn = document.querySelector("#close-menu-btn");
const siteMenuLabel = document.querySelector("#site-menu-label");
const elementList = [openMenuBtn, navigationMenu, closeMenuBtn, siteMenuLabel];
function toggleElements (elements) {
for (let element of elements) {
element.classList.toggle("hidden");
}
}
document.addEventListener("click", (event) => {
if (elementList.includes(event.target)) {
toggleElements(elementList);
}
})
</script>