const menu = document.querySelector(".menu");
const links = menu.querySelectorAll("a:not(.js-anchor--link)");
for (const el of links) {
el.addEventListener("click", function (e) {
e.preventDefault();
const ul = this.nextElementSibling;
if (ul !== null) {
ul.classList.toggle("menu-submenu--show");
}
let par = this.parentElement;
while (true) {
if (par.parentElement.classList.contains("menu")) break;
par = par.parentElement;
}
console.log(par)
const mainLiChild = menu.children;
for (const li of mainLiChild) {
if (li !== par) {
li.querySelectorAll(".menu-submenu").forEach(el => el.classList.remove("menu-submenu--show"));
}
}
})
}
One tiny addition is that, unlike getElementsByClassName, querySelectorAll returns a NodeList, and NodeList objects have a forEach built in. This means spreading to an array is not needed if you need forEach (note that other array methods like map are not built in, so you may want to spread then, or manually call map on the list via call()).
getElementsByClassName return HTMLCollections which do not have a forEach. They are, like NodeLists, array-like, though, so you can ultimately use array methods on them (more on that in the array-likes tip of the day: JavaScript Tips of the Day ).
Fair enough; I spend enough of my time programming in other languages that all I remembered was that querySelectorAll has an unpredictable (by me, not docs) subset of behavior that I’d expect from an array.
Creating engaging and entertaining content for designers and developers since 1998.