I have two parent items with sub-menus and have the code firing to open the current sub-menu while closing the other open ones.
But I can't seem to get the .toggleClass()
to fire on the open menu to close it (I want to toggle a menu item open/close).
<ul>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Thing 1</a></li>
<li><a href="#">Thing 2</a></li>
</ul>
</li>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Widget 1</a></li>
<li><a href="#">Widget 2</a></li>
</ul>
</li>
</ul>
And here is my current jquery
// main menu toggle of sub-menu
$(".menu-item-has-children > a").click(function(e) {
// remove .visible from other .sub-menu
$(".sub-menu").removeClass('visible');
// toggle the .visible class on the current parent item
$(this).next(".sub-menu").toggleClass('visible');
// prevent the <a> from default behavior
e.preventDefault();
});
CodePudding user response:
This doesn't work, because $(".sub-menu")
selects all sub-menus and removes the visible
class from each. Next toggleClass
adds again (toggle) the removed visible
class.
If you want to remove visible
from the other elements only, you must go up the hierarchy and fetch all sibling elements from the parent. Now visible
is removed from the other sub-menu only:
$(this).parent().siblings().children(".sub-menu").removeClass('visible');
// main menu toggle of sub-menu
$(".menu-item-has-children > a").click(function(e) {
// remove .visible from other .sub-menu
$(this).parent().siblings().children(".sub-menu").removeClass('visible');
// toggle the .visible class on the current parent item
$(this).next(".sub-menu").toggleClass('visible');
// prevent the <a> from default behavior
e.preventDefault();
});
.sub-menu {
display: none;
}
.sub-menu.visible {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Thing 1</a></li>
<li><a href="#">Thing 2</a></li>
</ul>
</li>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Widget 1</a></li>
<li><a href="#">Widget 2</a></li>
</ul>
</li>
</ul>
CodePudding user response:
What you've described seems to work, do you have a link to a non-working example?
// main menu toggle of sub-menu
$(".menu-item-has-children > a").click(function(e) {
// remove .visible from other .sub-menu
$(".sub-menu").removeClass('visible');
// toggle the .visible class on the current parent item
$(this).next(".sub-menu").toggleClass('visible');
// prevent the <a> from default behavior
e.preventDefault();
});
.sub-menu {
display: none;
}
.visible {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Thing 1</a></li>
<li><a href="#">Thing 2</a></li>
</ul>
</li>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Widget 1</a></li>
<li><a href="#">Widget 2</a></li>
</ul>
</li>
</ul>
CodePudding user response:
toggleClass is always do add class if use after removeClass
// main menu toggle of sub-menu
$(".menu-item-has-children > a").click(function(e) {
// check active
var isCurrentActive = $(this).next('.sub-menu').hasClass('visible')
// remove .visible from other .sub-menu
$(".sub-menu").removeClass('visible');
// if current menu deactive add visible
if(!isCurrentActive){
$(this).next(".sub-menu").addClass('visible');
}
// prevent the <a> from default behavior
e.preventDefault();
});
.sub-menu{ display:none }
.sub-menu.visible{ display:block }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Thing 1</a></li>
<li><a href="#">Thing 2</a></li>
</ul>
</li>
<li >
<a href="#">Services</a>
<ul >
<li><a href="#">Widget 1</a></li>
<li><a href="#">Widget 2</a></li>
</ul>
</li>
</ul>