I am following a css flex video and I am trying to build a menu with several levels. I am using jQuery to open and close a menu and sub-menu, and sub-sub-menu, etc.
Here is my demo.
- I click on "Contact"
- Then, I clik on "A propo" and "Contact" should close.
- I click on the first sub-menu (Item 1.2) => The first level should not close
- I click on the second sub-menu (Item 1.2.3) => All of this direct ul parent, should not close.
- Then now, when I click again to "Contact", all menu and sub-menus of "A propos" should close
My problem, I do not know how to target the first level of li.hasChildren and check all of child of other ul li.hasChildren and look for the children to close the opened menu and sub-menu.
Here is my script to close/open the selected menu, which works
( function( $ ) {
$( '.dropdown-toggle' ).click( function( e ) {
var _this = $( this );
e.preventDefault();
_this.toggleClass( 'toggled-on' );
_this.find('.fa').toggleClass( 'fa-angle-down fa-angle-up');
_this.parent().next( '.sub-menu' ).toggleClass( 'toggled-on' );
_this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
// HOW CAN I CHECK ALL OTHER MENUS
} );
})( jQuery );
Above, I created a variable _this
- How can I check for the first
li.hasChildren
from_this
- Then how can check if there is other parent
li.hasChildren
up to the first level of li - Then how can check all other branch of the tree to close the ul-su-menu bellow li.hasChildren, excepted for the tree that the click come from
I tried with parentUntil()
(this).parentsUntil("li.hasChildren").css( "background-color", "red" );
to mark with a class first level, but I apparently jQuery stop at the first li.hasChildren it meet, and do not continue until the first level
Note, when a menu or sub-menu is open, the ul take the class ul.toggled-on
. To close a sub-menu, we can use removeClass('.toggled-on')
here is my html code
<nav class="e-panel e-panel-row" role="navigation" aria-label="Main navigation">
<ul class="e-justify-content-space-beween bg-black">
<li class="hasChildren">
<div>
<a href="#">A propo</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
[12]
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a class="link" href="#">Item 1.1</a>
</div>
</li>
<li class="hasChildren">
<div>
<a href="#" class="link">Item 1.2</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
[1]
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a href="#">Item 1.2.1</a>
</div>
</li>
<li>
<div>
<a href="#">Item 1.2.2</a>
</div>
</li>
<li class="hasChildren">
<div>
<a href="#">Item 1.2.3</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
[1]
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu">
<li><div><a href="#">Item 1.2.3.1</a></div></li>
<li><div><a href="#">Item 1.2.3.2</a></div></li>
<li><div><a href="#">Item 1.2.3.3</a></div></li>
</ul>
</li>
</ul>
</li>
<li>
<div>
<a href="#">Item 333333</a>
</div>
</li>
</ul>
</li>
<li>
<div>
<a href="#">Team</a>
</div>
</li>
<li class="hasChildren">
<div>
<a href="#" class="link">Contact</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
[13]
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a href="#">Adresse</a>
</div>
</li>
<li>
<div>
<a href="#">Téléphone</a>
</div>
</li>
<li>
<div>
<a href="#">e-mail</a>
</div>
</li>
</ul>
</li>
<li>
<div>
<a href="#">Nos cours</a>
</div>
</li>
<li>
<div>
<a href="#">Menu 3</a>
</div>
</li>
<li>
<div>
<a href="#">Encore un beau menu 4</a>
</div>
</li>
<li>
<div>
<a href="#">Contact</a>
</div>
</li>
</ul>
</nav>
Then my question is, how can I check all ul.toggled-on, which does not belong of the branch where I clicked
Many thanks
2
Answers
I finally found a solution as the following
I hope, you will like it
You can set a class active for the last click on your menus.
Like this, you can do a loop with each() and check for unactive menu.
I commented my code.