Reputation: 77
Currently I have this working almost perfectly, but the user has the ability to open multiple sub-nav's at once, and I need any open sub-nav's to close when another one is open.
Basically, the jQuery that's beloe, I need to classes to be removed if a new sub-nav is clicked on, currently it only removes them if the same one is clicked.
HTML
<nav class="st-menu" id="menu-4a">
<ul>
<li>
<a href="#">Guidance Manual</a>
</li>
<li>
<a href="#">Resource Directory</a><div class="toggle-arrow"><img src="/assets/images/chevron-up-solid.svg"/></div>
<ul class="reg-subnav">
<li><a href="#">Stormwater Plan Review Resources</a></li>
<li><a href="#">Pilot Projects</a></li>
<li><a href="#">Proprietary Products</a></li>
<li><a href="#">Additional Resources</a></li>
</ul>
</li>
<li>
<a href="#">Stormwater 101</a><div class="toggle-arrow"><img src="/assets/images/chevron-up-solid.svg"/></div>
<ul class="reg-subnav">
<li><a href="#">Regulations</a></li>
<li><a href="#">Stormwater Management</a></li>
<li><a href="#">Stormwater Billing & Retrofits</a></li>
<li><a href="#">Green City, Clean Waters</a></li>
</ul>
</li>
<li>
<a href="#">Contact Us</a><div class="toggle-arrow"><img src="/assets/images/chevron-up-solid.svg"/></div>
<ul class="reg-subnav">
<li><a href="#">About Us</a></li>
<li><a href="#">Development Review Contacts</a></li>
</ul>
</li>
</ul>
</nav>
jQuery
$(".toggle-arrow").click(function(){
$(this).closest('li').find(".reg-subnav").toggleClass('open-sub');
$(this).closest('li').find('.arrow-image').toggleClass("flip");
});
Upvotes: 1
Views: 134
Reputation: 207557
You can use siblings and select the elements with the class and remove them.
$("nav").on("click", ".toggle-arrow", function(){
var currentLi = $(this).closest('li')
currentLi.find(".reg-subnav").toggleClass('open-sub');
currentLi.find('.toggle-arrow').toggleClass("flip");
//clean up the other open elements
var otherLis = currentLi.siblings()
otherLis.find(".open-sub").removeClass('open-sub')
otherLis.find(".flip").removeClass('flip')
});
.reg-subnav {
display: none;
}
.reg-subnav.open-sub {
display: block;
}
img {
width: 20px;
}
.toggle-arrow {
position: relative;
cursor: pointer;
display: inline-block;
}
.toggle-arrow img {
transform: rotateX(180deg);
transition: transform 0.75s;
transform-style: preserve-3d;
}
.toggle-arrow.flip img {
transform: rotateY(0deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="st-menu" id="menu-4a">
<ul>
<li>
<a href="#">Guidance Manual</a>
</li>
<li>
<a href="#">Resource Directory</a><div class="toggle-arrow"><img src="https://image.flaticon.com/icons/svg/120/120906.svg"/></div>
<ul class="reg-subnav">
<li><a href="#">Stormwater Plan Review Resources</a></li>
<li><a href="#">Pilot Projects</a></li>
<li><a href="#">Proprietary Products</a></li>
<li><a href="#">Additional Resources</a></li>
</ul>
</li>
<li>
<a href="#">Stormwater 101</a><div class="toggle-arrow"><img src="https://image.flaticon.com/icons/svg/120/120906.svg"/></div>
<ul class="reg-subnav">
<li><a href="#">Regulations</a></li>
<li><a href="#">Stormwater Management</a></li>
<li><a href="#">Stormwater Billing & Retrofits</a></li>
<li><a href="#">Green City, Clean Waters</a></li>
</ul>
</li>
<li>
<a href="#">Contact Us</a><div class="toggle-arrow"><img src="https://image.flaticon.com/icons/svg/120/120906.svg"/></div>
<ul class="reg-subnav">
<li><a href="#">About Us</a></li>
<li><a href="#">Development Review Contacts</a></li>
</ul>
</li>
</ul>
</nav>
Upvotes: 1
Reputation: 221
Could be done with removeClass
$(".toggle-arrow").click(function(){
$(".reg-subnav").not($(this).closest("li").find(".reg-subnav")).removeClass("open-sub");
$(this).closest('li').find(".reg-subnav").toggleClass('open-sub');
$(this).closest('li').find('.arrow-image').toggleClass("flip");
});
And you could clean up your code even more by using the siblings selector:
$(".toggle-arrow").click(function(){
$(".reg-subnav").not($(this).siblings(".reg-subnav")).removeClass("open-sub");
$(this).siblings(".reg-subnav").toggleClass('open-sub');
$(this).siblings('.arrow-image').toggleClass("flip");
});
EDIT: Per @epascarello, This could also be made more performant by storing the subnav so it's not queried for twice:
$(".toggle-arrow").click(function(){
var $thisSubnav = $(this).siblings(".reg-subnav");
$(".reg-subnav").not($thisSubnav).removeClass("open-sub");
$thisSubnav.toggleClass('open-sub');
$(this).siblings('.arrow-image').toggleClass("flip");
});
Upvotes: 1
Reputation: 3457
How about this one? You should remove class 'open-sub' from all of lists.
$(".toggle-arrow").click(function(){
$("nav.st-menu").find(".reg-subnav").removeClass('open-sub');
$(this).closest('li').find(".reg-subnav").toggleClass('open-sub');
$("nav.st-menu").find(".arrow-image").removeClass('flip');
$(this).closest('li').find('.arrow-image').toggleClass("flip");
});
Upvotes: 1