When adding the option to open only one sub-menu at a time, it generates the error that only one sub-menu should always be open and I do not understand the reason, I attach a test image.
enter image description here enter image description here
As you can see when one clicks it displays the menu but if I click it again it does not close but it opens again, in the image you see the closed arrow "↟" an up arrow and when the sub-menu opens the arrow changes down "↡", I say this to show the error that the menu never closes.
This is the html code `
<nav class='animated flipInX'>
<ul>
<li>
<a href='#'>
<div class='fa fa-home'></div>
</a>
</li>
<li>
<a href='#'>
About
</a>
</li>
<li class='sub-menu'>
<a href='#'>
Products
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li class='sub-menu'>
<a href='#'>
Services
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li>
<a href='#'>
Contact Us
</a>
</li>
</ul>
</nav>
This is the js code
$(".sub-menu ul").hide()
$(".sub-menu a").click(function () {
$(".sub-menu ul").not($(this)).hide();
$(this).parent(".sub-menu").children("ul").slideToggle("200");
$(this).find("i.fa").toggleClass("fa-angle-up fa-angle-down");
});
` I ask for help to solve this problem, the idea is to let you close the normal menu but do not change the functionality of not being able to open more than one menu at the same time.
I tried many jquery options but I don't understand the error yet.
CodePudding user response:
Here you go,
$(".sub-menu ul").hide();
function recycle() {
if ($(".submnu-2").length && !$(".submnu-1").length) {
$(".submnu-2").addClass("submnu-1").removeClass("submnu-2");
}
}
function removeold() {
if ($(".submnu-2").length) {
$(".submnu-1").siblings("ul").hide();
$(".submnu-1").find("i.fa").toggleClass("fa-angle-up fa-angle-down");
$(".submnu-1").removeClass("show").removeClass("submnu-1");
recycle();
}
}
$(".sub-menu a").click(function () {
event.preventDefault();
if ($(this).hasClass("show")) {
$(this).removeClass("show");
$(this).siblings("ul").hide();
$(this).find("i.fa").toggleClass("fa-angle-up fa-angle-down");
recycle();
} else {
removeold();
$(this).addClass("show").addClass("submnu-2");
$(this).siblings("ul").show();
$(this).find("i.fa").toggleClass("fa-angle-up fa-angle-down");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class='animated flipInX'>
<ul>
<li>
<a href='#'>
<div class='fa fa-home'></div>
</a>
</li>
<li>
<a href='#'>
About
</a>
</li>
<li class='sub-menu'>
<a href='#'>
Products
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li class='sub-menu'>
<a href='#'>
Products2
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li class='sub-menu'>
<a href='#'>
Services
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li>
<a href='#'>
Contact Us
</a>
</li>
</ul>
</nav>
CodePudding user response:
A simple solution, with one stack
keeping track of the open items. Easy to change the number of simultaneously allowed open sub-menus. The only addition is the open
class (and the corresponding CSS
).
let stack = []
$(".sub-menu").on("click", function() {
if ($(this).hasClass("open")) {
// if you click on a sub-menu, that is open
// close it and remove it from the stack
$(this).removeClass("open")
stack = stack.filter((item) => item != this)
} else {
// if you click on a sub-menu, that is not open
// open it and add it to the stack (as last item)
$(this).addClass("open")
stack.push(this)
if (stack.length === 3) {
// if the stack has 3 elements (actually, more than 2)
// then remove the first element from the stack
// and remove the "open" class from it
const that = stack.shift()
$(that).removeClass("open")
}
}
})
.sub-menu>ul {
display: none;
}
.sub-menu.open>ul {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class='animated flipInX'>
<ul>
<li>
<a href='#'>
<div class='fa fa-home'></div>
</a>
</li>
<li>
<a href='#'>
About
</a>
</li>
<li class='sub-menu'>
<a href='#'>
Products
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li class='sub-menu'>
<a href='#'>
Products2
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li class='sub-menu'>
<a href='#'>
Services
<i class='fa fa-angle-down'></i>
</a>
<ul>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
<li>
<a href='#'>
Product Item
</a>
</li>
</ul>
</li>
<li>
<a href='#'>
Contact Us
</a>
</li>
</ul>
</nav>