I have build an offcnavas menu with 3 category levels which are nested within the HTML markup. Category level1 opens category level2 which opens the level 3. Here is the snippet:
const items = document.querySelectorAll('.navigation-offcanvas-list-item');
items.forEach(item => {
item.addEventListener('click', event => {
const containsIsOpen = item.classList.contains("is-open")
if (!containsIsOpen) {
item.classList.add("is-open")
} else {
item.classList.remove("is-open")
}
})
})
.third .navigation-offcanvas-list-item {
overflow: hidden;
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
max-height: 0;
transform: scaleY(0);
transform-origin: top;
}
.second {
overflow: hidden;
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
max-height: 0;
transform: scaleY(0);
transform-origin: top;
}
.second .navigation-offcanvas-list-item.is-open .third .navigation-offcanvas-list-item {
max-height: none;
transform: scaleY(1);
}
.first .navigation-offcanvas-list-item.is-open .second {
max-height: none;
transform: scaleY(1);
}
<div class="navigation-offcanvas-container js-navigation-offcanvas">
<div class="navigation-offcanvas-overlay-content">
<!-- FIRST LEVEL -->
<ul class="list-unstyled navigation-offcanvas-list">
<li>
<div class="first">
<ul>
<li class="navigation-offcanvas-list-item" data-first-trigger="id1" data-offcanvas-menu-level="level1">
<div class="navigation-offcanvas-link nav-item">
<span class="navigation-offcanvas-link-icon js-navigation-offcanvas-loading-icon">Category LEVEL1</span>
</div>
<div class="second" data-first-offcanvas="id1">
<ul>
<li class="navigation-offcanvas-list-item" data-second-trigger="idd1" data-offcanvas-menu-level="level2">
<div class="navigation-offcanvas-link nav-item">
<span class="navigation-offcanvas-link-icon js-navigation-offcanvas-loading-icon">Category1 LEVEL2</span>
</div>
<div class="third" data-second-offcanvas="idd1">
<ul>
<li class="navigation-offcanvas-list-item">final link</li>
<li class="navigation-offcanvas-list-item">final link</li>
<li class="navigation-offcanvas-list-item">final link</li>
</ul>
</div>
</li>
<li class="navigation-offcanvas-list-item" data-second-trigger="idd2" data-offcanvas-menu-level="level2">
<div class="navigation-offcanvas-link nav-item">
<span class="navigation-offcanvas-link-icon js-navigation-offcanvas-loading-icon">Category2 LEVEL2</span>
</div>
<div class="third" data-second-offcanvas="idd2">
<ul>
<li class="navigation-offcanvas-list-item">final link</li>
<li class="navigation-offcanvas-list-item">final link</li>
<li class="navigation-offcanvas-list-item">final link</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
Now the problem is, if I open the first level the class is-open
is getting added correctly. The same is true for level2. The submenu opens correctly.
But now I need to close the second submenu when clicking the second level link, as well as the first submenu when clicking the first level link. The problem is (I guess, but I’m not sure), the HTML markup is so nested, that when I click on the second level link to open the second submenu, it will remove is-open
from the entire markup. You can see the behaviour in the snippet.
How would I open and close the submenus correctly?
2
Answers
Use this:
event.stopPropagation()