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>