I have a nested list that looks like this:
<ul >
<li>
<a href="#">Menu item</a>
<ul >
<li>
<a href="#">Subitem-1</a>
<ul>
<li>Sub-Subitem-1</li>
<li>Sub-Subitem-2</li>
<li>Sub-Subitem-3</li>
</ul>
</li>
<li>
<a href="#">Subitem-2</a>
<ul>
<li>Sub-Subitem-1</li>
<li>Sub-Subitem-2</li>
<li>Sub-Subitem-3</li>
</ul>
</li>
</ul>
</li>
</ul>
When hovering the ul.menu-wrapper > li
item, an .active
class is applied to the first ul.sub-menu
and the first li
item within the submenu list:
$('ul.menu-wrapper').children().hover(
function() {
let subMenu = $(this).find('ul.sub-menu').first()
subMenu.addClass('active')
subMenu.children().first().addClass('active')
},
function() {
let subMenu = $(this).find('ul.sub-menu').first()
subMenu.removeClass('active')
}
)
Now I need to hover the li
items within the ul.sub-menu
and change the .active
class to the item being hovered.
I can do this by adding a .hover()
method on the subMenu.children()
items.
$('ul.menu-wrapper').children().hover(
function() {
...
subMenu.children().hover(
function() {
$(this).addClass('active')
},
function() {
$(this).removeClass('active')
}
)
},
function() {
...
}
)
When a submenu item has been hovered and the pointer goes back to the ul.menu-wrapper > li
item, I want to have at least one ul.sub-menu > li
item with the .active
class.
Currently the mouseleave
method is removing the class when pointer is moved from a submenu back to the parent list item. How can I prevent this to always have one ul.sub-menu > li
with .active
class at all times?
Demo https://jsfiddle.net/5Lwyh3xs/
CodePudding user response:
On mouse out add active class to the first li if no li items have active class.
$('ul.menu-wrapper').children().hover(
function() {
let subMenu = $(this).find('ul.sub-menu').first()
subMenu.addClass('active')
subMenu.children().first().addClass('active')
subMenu.children().hover(
function() {
$(this).addClass('active').siblings().removeClass('active')
},
function() {
$(this).removeClass('active')
if($('.sub-menu > li.active').length == 0) {
subMenu.children().first().addClass('active')
}
}
)
},
function() {
let subMenu = $(this).find('ul.sub-menu').first()
subMenu.removeClass('active')
}
)
body {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
ul.menu-wrapper {
height: 80px;
}
ul.menu-wrapper {
background: gray;
}
ul.menu-wrapper>li {
height: 100%;
display: flex;
align-items: center;
}
ul.menu-wrapper ul.sub-menu {
visibility: hidden;
position: absolute;
top: 80px;
}
ul.menu-wrapper ul.sub-menu.active {
visibility: visible;
}
ul.menu-wrapper ul.sub-menu.active>li.active {
background: darkmagenta;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav role="navigation" id="navigation-wrapper">
<ul >
<li>
<a href="#">Menu item</a>
<ul >
<li>
<a href="#">Subitem-1</a>
<ul>
<li>Sub-Subitem-1</li>
<li>Sub-Subitem-2</li>
<li>Sub-Subitem-3</li>
</ul>
</li>
<li>
<a href="#">Subitem-2</a>
<ul>
<li>Sub-Subitem-1</li>
<li>Sub-Subitem-2</li>
<li>Sub-Subitem-3</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>