Working on a menu where I want to close all sub navigations when clicking on another link with a sub navigation, it currently only collapses the sub navigation on the same level but not the deeper ones.
Example:
- Click on A1 > A2A > A3A > A4A
- Then click on B1
- Click on A1 again
- You see that A2A, A3A and A4A are still completely unfolded
$('li.has-children').click(function() {
$(this).children('.wrap').addClass('active');
$(this).closest('ul').children('li').not(this).children('.wrap').removeClass('active');
});
ul,
ul li {
margin:0;
padding:0;
list-style:none;
}
.wrap {
display: none;
}
.active {
display: inline-block;
}
.has-children-level1 {
display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li >
<a >link A1</a>
<div >
<ul>
<li >
<a >link A2A</a>
<div >
<ul>
<li >
<a >link A3A</a>
<div >
<ul>
<li >
<a >link A4A</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link A2B</a>
<div >
<ul>
<li >
<a >link A3B</a>
<div >
<ul>
<li >
<a >link A4B</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link B1</a>
<div >
<ul>
<li >
<a >link B2A</a>
<div >
<ul>
<li >
<a >link B3A</a>
<div >
<ul>
<li >
<a >link B4A</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link B2B</a>
<div >
<ul>
<li >
<a >link B3B</a>
<div >
<ul>
<li >
<a >link B4B</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
CodePudding user response:
I have slightly modified your logic to check if the parent level is clicked, remove the active class from all the child elements.
if($(this).hasClass('has-children')){
$(this).siblings().find('*').removeClass('active')
}
Also, I have added e.stopPropagation()
to prevent bubbling
of the click event
Working Code below
$('li.has-children').click(function(e) {
e.stopPropagation();
$(this).children('.wrap').addClass('active');
if ($(this).hasClass('has-children')) {
$(this).siblings().find('*').removeClass('active')
}
});
ul,
ul li {
margin: 0;
padding: 0;
list-style: none;
}
.wrap {
display: none;
}
.active {
display: inline-block;
}
.has-children-level1 {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li >
<a >link A1</a>
<div >
<ul>
<li >
<a >link A2A</a>
<div >
<ul>
<li >
<a >link A3A</a>
<div >
<ul>
<li >
<a >link A4A</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link A2B</a>
<div >
<ul>
<li >
<a >link A3B</a>
<div >
<ul>
<li >
<a >link A4B</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link B1</a>
<div >
<ul>
<li >
<a >link B2A</a>
<div >
<ul>
<li >
<a >link B3A</a>
<div >
<ul>
<li >
<a >link B4A</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link B2B</a>
<div >
<ul>
<li >
<a >link B3B</a>
<div >
<ul>
<li >
<a >link B4B</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
CodePudding user response:
before setiing the active one reomve all the other active.
$('li.has-children').click(function() {
var $this = $(this)
var p = $this.parents('.has-children');
$('div.wrap').not(this).removeClass('active')
if(p.length){
$(`.wrap`,p).not($this.find('.wrap .wrap')).addClass('active')
}
else{
$this.children('.wrap').addClass('active');
}
return false
});
ul,
ul li {
margin:0;
padding:0;
list-style:none;
}
.wrap {
display: none;
}
.active {
display: block;
}
.has-children-level1 {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li >
<a >link A1</a>
<div >
<ul>
<li >
<a >link A2A</a>
<div >
<ul>
<li >
<a >link A3A</a>
<div >
<ul>
<li >
<a >link A4A</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link A2B</a>
<div >
<ul>
<li >
<a >link A3B</a>
<div >
<ul>
<li >
<a >link A4B</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link B1</a>
<div >
<ul>
<li >
<a >link B2A</a>
<div >
<ul>
<li >
<a >link B3A</a>
<div >
<ul>
<li >
<a >link B4A</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li >
<a >link B2B</a>
<div >
<ul>
<li >
<a >link B3B</a>
<div >
<ul>
<li >
<a >link B4B</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>