I have a dropdown menu that on click, displays a submenu of list items.
Everything works great except the PARENT 2 submenu, if active, does NOT turn off if I click on the PARENT 3 link with a dropdown.
$(function () {
$('nav ul li a:not(:only-child)').click(function (e) {
$(this).siblings('.nav-dropdown').toggle();
$('.dropdown').not($(this).siblings()).hide();
e.stopPropagation();
});
$('html').click(function () {
$('.nav-dropdown').hide();
});
});
So if I click PARENT 2, the dropdown appears. If I then click PARENT 3, its dropdown also appears (and I need PARENT 2 dropdown to disappear). How to make sure that any menu item clicked removes any instance of an open submenu?
<nav>
<ul class="nav_links">
<li>Parent 1</li>
<li>Parent 2
<ul class="nav-dropdown">
<li>
Child 1
</li>
<li>
Child 2
</li>
</ul>
</li>
<li>Parent 3<i class="fa-solid fa-angle-down"></i>
<ul class="nav-dropdown">
<li>
Child 1
</li>
<li>
Child 2
</li>
</ul>
</li>
<li>Parent 4</li>
</ul>
</nav>
Your problem was that there isn't any element with the class dropdown.
So $('.dropdown').not($(this).siblings()).hide(); didn't work.
Try this:
$(function() {
$('nav ul li a:not(:only-child)').click(function(e) {
$(this).siblings('.nav-dropdown').toggle();
$('.nav-dropdown').not($(this).siblings()).hide();
e.stopPropagation();
});
$('html').click(function() {
$('.nav-dropdown').hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul class="nav_links">
<li>Parent 1</li>
<li>Parent 2
<ul class="nav-dropdown">
<li>
Child 1
</li>
<li>
Child 2
</li>
</ul>
</li>
<li>Parent 3<i class="fa-solid fa-angle-down"></i>
<ul class="nav-dropdown">
<li>
Child 1
</li>
<li>
Child 2
</li>
</ul>
</li>
<li>Parent 4</li>
</ul>
</nav>
Related
<li class="cate-item">
<button class="cate-label" >item 1 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
<li class="cate-item">
<button class="cate-label" >item 2 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
This li item is generated dynamically I want to toggle li on the cate-label button click. for that, I did the following code
$(document).on("click", "#categoryList > li .cate-label", function () {
var currentItem = $(this).closest("li");
ItemToHide = $("#categoryList > li").not(currentItem);
ItemToHide.removeClass("active-item");
ItemToHide.find(".sub-cate").hide();
currentItem.toggleClass("active-item");
}
);
when I try to hide item using ItemToHide.find(".sub-cate").hide(); it didn't hide anything . I tried to find the length of the item using ItemToHide.find(".sub-cate").length but it returned 0.
Lower your event handling to something closer. I wrapped everything in a <menu> tag and registered the click event to it instead of document. It doesn't make much of a difference performance wise but I suggest it because it's looks as if your perspective is skewed if dealing with a larger view of the DOM and you'll be error prone:
var currentItem = $(this).closest("li");
ItemToHide = $("#categoryList > li").not(currentItem);
ItemToHide.removeClass("active-item");
ItemToHide.find(".sub-cate").hide();
currentItem.toggleClass("active-item");
That nightmare is now:
$(this).next('.sub-categ').toggle('ease-out');
$('menu').on("click", ".cate-label", toggleList);
function toggleList(e) {
$(this).next('.sub-categ').toggle('ease-out');
};
<menu>
<li class="cate-item">
<button class="cate-label">item 1 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
<li class="cate-item">
<button class="cate-label">item 2 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
</menu>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Actually, the name of the class is not correct. Should be 'sub-cate', not 'sub-categ'.
$(document).on("click", "#categoryList > li .cate-label", function () {
var currentItem = $(this).closest("li");
ItemToHide = $("#categoryList > li").not(currentItem);
ItemToHide.removeClass("active-item");
ItemToHide.find(".sub-cate").hide();
currentItem.toggleClass("active-item");
});
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div id="categoryList">
<li class="cate-item">
<button class="cate-label" >item 1 </button>
<ul class="sub-cate"><!--rename the class name-->
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
<li class="cate-item">
<button class="cate-label" >item 2 </button>
<ul class="sub-cate"><!--rename the class name-->
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
</div>
Wondering if anyone can help, please.
I've got some jQuery setup for my sub-menu in WordPress. It works perfectly until I have a sub-menu within a sub-menu. The classes don't change in WordPress so the jQuery no longer works.
Here's my jQuery:
$('.mobile li > .sub-menu').parent().click(function() {
$(".sub-menu").slideUp();
var submenu = $(this).children('.sub-menu');
if ( $(submenu).is(':hidden') ) {
$(submenu).slideDown(200);
} else {
$(submenu).slideUp(200);
}
});
Here's an example of how WordPress outputs the menu code:
<ul id="menu-main-menu" class="mobile">
<li>
Item
<ul class="sub-menu">
<li>
Item
<ul class="sub-menu">
<li>
Item
</li>
</ul>
</li>
</ul>
</li>
</ul>
Any ideas of how to amend my code? Currently when I click the item within the two sub-menu then the parent sub-menu closes.
Try with this simplified handler:
$('.mobile li > a').click(function() {
$(this).siblings('.sub-menu').slideToggle(200);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu-main-menu" class="mobile">
<li>
Item
<ul class="sub-menu">
<li>
Item
<ul class="sub-menu">
<li>
Item
</li>
</ul>
</li>
</ul>
</li>
</ul>
I am attempting to create a pure CSS multi-level dropdown menu. I got it to work for hovering. However, I only want it to hover in the submenu, but the main menu item to be clickable to expand the menu. I tried to add jquery to override the hovering to clickable action, but it's not working. What am I doing wrong?
<nav class="nav">
Home
<li class="menu-item subItem">Menu1<b class="down-arrow"></b>
<ul class="submenu">
<li class="menu-item">Menu Item 1</li>
<li class="menu-item subItem">Submenu <b class="right-arrow"></b></span>
<ul class="submenu">
<li class="menu-item">Sub1</li>
<li class="menu-item">Sub2</li>
<li class="menu-item subItem">3rd Level <b class="right-arrow"></b></span>
<ul class="submenu">
<li class="menu-item">Level1</li>
<li class="menu-item">Level2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<script>
$(function() {
$('.menu-item').on('click',function(e) {
e.preventDefault();
$('.submenu').show();
});
});
</script>
I've got a jquery vertical accordion navigation menu. Everthing's working fine but when i expand a list item and if I click on a list item it's getting hidden.
Here's the code:
HTML :
<div class="sidebar">
<ul>
<li>
Item 1 <i class="sidebar-icon glyphicon glyphicon-chevron-left"></i>
<ul class="sub-menu">
<li>
Sub Item 1
</li>
<li>
Sub Item 2
</li>
</ul>
</li>
<li>
Item 2 <i class="sidebar-icon glyphicon glyphicon-chevron-left"></i>
<ul class="sub-menu">
<li>
Sub Item 1
</li>
<li>
Sub Item 2
</li>
<li>
Sub Item 3
</li>
</ul>
</li>
<li>
Item 3 <i class="sidebar-icon glyphicon glyphicon-chevron-left"></i>
<ul class="sub-menu">
<li>
Sub Item 1
</li>
<li>
Sub Item 2
</li>
<li>
Sub Item 3
</li>
</ul>
</li>
<li>
Item 4 <i class="sidebar-icon glyphicon glyphicon-chevron-left"></i>
<ul class="sub-menu">
<li>
Sub Item 1
</li>
<li>
Sub Item 2
</li>
</ul>
</li>
</ul>
</div>
JS :
function toggleAccordion(li) {
if(li.hasClass('active')) {
li.removeClass('active');
$('.sub-menu', li).slideUp();
$('i', li).removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-left');
}
else {
$('.sidebar > ul > li.active .sub-menu').slideUp();
$('li i').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-left');
$('li.active').removeClass('active');
li.addClass('active');
$('.sub-menu', li).slideDown();
$('i', li).removeClass('glyphicon-chevron-left').addClass('glyphicon-chevron-down');
}
};
$('.sidebar > ul > li').click(function(ev) {
ev.stopPropagation();
toggleAccordion($(this));
});
$('.sidebar > ul > li > a').click(function(ev) {
ev.stopPropagation();
toggleAccordion($(this).parent());
});
I do want it to be collapsed when clicked on a list item that's been expanded.
And I want it clickable in the entire row.
If i make the click function to .sidebar ul li a it's working fine. But I'm able to click only on the text to get the accordion effect.
Please help me.
You were not stopping the propagation of click event from the sub items
$('.sidebar > ul > li').click(function (ev) {
toggleAccordion($(this));
}).find('ul').hide();
$('.sidebar li').click(function (e) {
e.stopPropagation()
});
Demo: Fiddle
I have a simple drop down menu. When you click .drop-down, a sub menu slides down. However, if you click any of the children of .drop-down, it slides back up again. I want only the .drop-down that was clicked to slide the menu, none of the its descendents.
Here it is in action: http://jsfiddle.net/tmyie/uXn5k/2/
<ul>
<li class="drop-down">
Main
<ul class="sub-menu">
<li>Sub </li>
<li>Sub </li>
<li>Sub </li>
</ul>
</li>
<li>Main </li>
<li>Main </li>
<li>Main </li>
<li>Main </li>
</ul>
jQuery
$( ".drop-down" ).click(function() {
$('.sub-menu').slideToggle();
});
$('.drop-down').fadeTo('slow', 0.3);
http://jsfiddle.net/tmyie/uXn5k/2/
Target the a specifically
$( ".drop-down>a" ).click(function() {
$('.sub-menu').slideToggle();
});
$('.drop-down').fadeTo('slow', 0.3);
Or, just move the class from the li to the a
<ul>
<li>
Main
<ul class="sub-menu">
<li>Sub </li>
<li>Sub </li>
<li>Sub </li>
</ul></li>
<li>Main </li>
<li>Main </li>
<li>Main </li>
<li>Main </li>
</ul>
EDIT:
By the way, you're going to run into trouble with multiple dropdowns using this script. Consider making the following changes:
$( ".drop-down>a" ).on("click", function() {
$(this).siblings('.sub-menu').slideToggle();
});
$('.drop-down').fadeTo('slow', 0.3);
http://jsfiddle.net/uXn5k/6/