I have been trying for hours now, but can not figure my way out of this one. The Menu contains a regular submenu which gets an “active” class. Great, done with foreach. But how can I remove the active class when the user clicks anywhere in the document?
If I put an id on the body that removes the “active” class with an event listener, it will be removed without being present. Should I use “contains()”? Tried but con not get it to work either. Code is as plain as possible. Thank you for any help!!!
Link to Codepen: https://codepen.io/jaeiko/pen/OJOZRgm
<div id="nav__menu">
<ul class="navigation__desktop">
<li> <a href="#"> MenuItemOne</a></li>
<li> <a class="drop-down-items sub" href="#"> MenuItemTwo/Sub</a>
<ul class="navigation__desktop__dropdown">
<li> <a href="#"> SubMenuOne</a></li>
<li> <a href="#"> SubMenuTwo</a></li>
<li> <a href="#"> SubMenuThree</a></li>
<li> <a href="#"> SubMenuFour</a></li>
<li> <a href="#"> SubMenuFive</a></li>
<li> <a href="#"> SubMenuSix</a></li>
<li> <a href="#"> SubMenuSeven</a></li>
</ul>
</li>
<li> <a href="#"> MenuItemTwo</a></li>
<li> <a class="drop-down-items sub" href="#"> MenuItemThree/Sub</a>
<ul id="service-submenu" class="navigation__desktop__dropdown">
<li> <a href="#"> SubMenuEight</a></li>
<li> <a href="#"> SubMenuNine</a></li>
<li> <a href="#"> SubMenuTen</a></li>
</ul>
</li>
<li> <a href="#"> MenuItemFour</li></a>
</ul>
</div>
////// SCSS
.navigation__desktop {
display: flex;
justify-content: space-evenly;
position: relative;
a {
padding: 0.5rem;
display: block;
text-decoration: none;
font-weight: bold;
font-family: sans-serif;
}
}
.navigation__desktop__dropdown {
position: absolute;
display: flex;
flex-direction: column;
background-color: white;
border-radius: 0.1rem;
box-shadow: 0 0 10px #718096;
display: none;
text-transform: none;
}
.active {
display: block;
}
li {
list-style-type: none;
}
.sub {
color: red;
}
///////////// JS
/// Variables
let dropDownItems = document.querySelectorAll(".drop-down-items");
let dropDownUL = document.querySelectorAll(".navigation__desktop__dropdown");
/// Dropdown
dropDownItems.forEach(item => {
item.addEventListener("click", (e) => {
e.preventDefault();
let showMenuItem = item.nextElementSibling;
showMenuItem.classList.add("active");
})
})
[1]: https://codepen.io/jaeiko/pen/OJOZRgm
Advertisement
Answer
In your case i would create a global click event and check if the clicked element is a link, if not remove the active class for others.
/// Variables
let dropDownItems = document.querySelectorAll(".drop-down-items");
let dropDownUL = document.querySelectorAll(".navigation__desktop__dropdown");
/// Dropdown
dropDownItems.forEach(item => {
item.addEventListener("click", (e) => {
e.preventDefault();
let showMenuItem = item.nextElementSibling;
showMenuItem.classList.add("active");
})
})
// Add a global click handler
window.addEventListener('click', (e) => {
if (e.target.tagName !== 'A') {
dropDownItems.forEach((item) => {
let shownMenuItem = item.nextElementSibling;
if (shownMenuItem.classList.contains('active')) {
shownMenuItem.classList.remove('active');
}
});
}
});.navigation__desktop {
display: flex;
justify-content: space-evenly;
position: relative;
}
a {
padding: 0.5rem;
display: block;
text-decoration: none;
font-weight: bold;
font-family: sans-serif;
}
.navigation__desktop__dropdown {
position: absolute;
display: flex;
flex-direction: column;
background-color: white;
border-radius: 0.1rem;
box-shadow: 0 0 10px #718096;
display: none;
text-transform: none;
}
.active {
display: block;
}
li {
list-style-type: none;
}
.sub {
color: red;
} <div id="nav__menu">
<ul class="navigation__desktop">
<li> <a href="#"> MenuItemOne</a></li>
<li> <a class="drop-down-items sub" href="#"> MenuItemTwo/Sub</a>
<ul class="navigation__desktop__dropdown">
<li> <a href="#"> SubMenuOne</a></li>
<li> <a href="#"> SubMenuTwo</a></li>
<li> <a href="#"> SubMenuThree</a></li>
<li> <a href="#"> SubMenuFour</a></li>
<li> <a href="#"> SubMenuFive</a></li>
<li> <a href="#"> SubMenuSix</a></li>
<li> <a href="#"> SubMenuSeven</a></li>
</ul>
</li>
<li> <a href="#"> MenuItemTwo</a></li>
<li> <a class="drop-down-items sub" href="#"> MenuItemThree/Sub</a>
<ul id="service-submenu" class="navigation__desktop__dropdown">
<li> <a href="#"> SubMenuEight</a></li>
<li> <a href="#"> SubMenuNine</a></li>
<li> <a href="#"> SubMenuTen</a></li>
</ul>
</li>
<li> <a href="#"> MenuItemFour</li></a>
</ul>
</div>