I know this question has been asked before, but this one has a bit of a twist.
I've seen a few downvotes on this questions. Please be so kind as to let me know your reasons for downvoting so that I will be able to correct this in future. Thanks for your input all.
I have a single page scroll website with a nav menu overlay on screens smaller than 992px. The menu toggles fine, however when a nav link is clicked the nav menu remains open with the exception of the first nav-link.
I like to have every link closing the nav menu on click.
So How do get all the nav links to close the nav menu on click? I have a hunch it has to do with using querySelectorAll
instead of just querySelector
.
Here's a link to the site: https://portfolioprime.github.io/robotics/
Any assistance would be greatly appreciated.
Here's the navigation html.
HTML
<body>
<header>
<nav class="nav">
<!-- Nav Menu -->
<ul class="nav-list">
<li class="nav-item">
<a href="#showcase" class="nav-link">Home</a></li>
<li class="nav-item">
<a href="#robots" class="nav-link">Robots</a></li>
<li class="nav-item">
<a href="#projects" class="nav-link">Projects</a></li>
<li class="nav-item">
<a href="#research" class="nav-link">Research</a></li>
<li class="nav-item">
<a href="#explore" class="nav-link">Explore</a></li>
<li class="nav-item">
<a href="#prosthetics" class="nav-link">Prosthetics</a></li>
<li class="nav-item">
<a href="#contact" class="nav-link">Contact</a></li>
</ul>
<!-- Menu-toggle -->
<div class="menu-toggle">
<i class="fas fa-bars"></i>
<i class="fas fa-times"></i>
</div>
</nav>
</header>
</body>
And here's the Javascript.
JS
// Select element function
const selectElement = function (element) {
return document.querySelector(element);
};
let menuToggler = selectElement('.menu-toggle');
let body = selectElement('body');
let menuClose = selectElement('.nav-link');
// Open/Close menu on .menu-toggle click
menuToggler.addEventListener('click', function () {
body.classList.toggle('open');
});
// Close menu on .nav-link click
menuClose.addEventListener('click', function () {
body.classList.remove('open');
});
And you may be interested in the CSS for the .open
class that is appended to the body with javascript.
CSS
.open .nav-list {
bottom: 0;
}
.nav-link:hover {
border-bottom: none;
}
.menu-toggle {
display: block;
}
.open .menu-toggle .fa-bars {
display: none;
}
.open .menu-toggle .fa-times {
display: block;
position: fixed;
right: 2.7rem;
top: 2rem;
}
Your hunch is totally correct. This does it.
// Select element function
const selectElement = (element) =>
document.querySelector(element);
const getAllWithClass = (className) =>
document.getElementsByClassName(className);
const
body = selectElement('body'),
// Converts the returned collection to a proper Array
navLinks = Array.from(getAllWithClass("nav-link"));
// Close menu on .nav-link click
navLinks.forEach(link => { // The Array method `forEach` loops through
link.addEventListener('click', function() {
body.classList.remove('open');
console.log("(No more blue background means it's closed)");
});
});
.open .nav-list {
background-color: lightskyblue;
}
<body class="open">
<ul class="nav-list">
<li class="nav-item">
<a href="#showcase" class="nav-link">Home</a></li>
<li class="nav-item">
<a href="#robots" class="nav-link">Robots</a></li>
<li class="nav-item">
<a href="#projects" class="nav-link">Projects</a></li>
</ul>
</body>
Note: I think it would be better to add a single click-listener on the whole menu, (and check that the target of any click event is a nav-link before proceeding). But since you wanted to see how to add multiple listeners at once, I stuck with this.