I have a simple nav structure for a nav that has toggles to open and close sub-menus. However, when I click on a nested menu the toggle works, but also closes the parent sub-menu. How can I set it so that the parent doesn't close on the click of the nested menu?
jQuery(document).ready(function($) {
//Toggle sub-menus
$('#menu .has-children').on('click', function(event) {
event.preventDefault();
$(this).children('.sub-menu').slideToggle(500);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li>item 1</li>
<li class="has-children">item 2
<ul class="sub-menu">
<li>sub-item 1</li>
</ul>
</li>
<li class="has-children">item 3
<ul class="sub-menu">
<li>sub-item 1</li>
<li class="has-children">sub-item 2
<ul class="sub-menu">
<li>sub-sub-item 1</li>
</ul>
</li>
</ul>
</li>
</ul>
event.preventDefault(); doesn't stop the event from traveling up the tree, you need to use event.stopPropagation(); to stop the click from also triggering the click event listeners on parent elements.
(You could also add this to li inside sub menus without .has-children, to prevent them from closing parent menus, though that's unnecessary if those nav items link to other pages)
jQuery(document).ready(function($) {
//Toggle sub-menus
$('#menu .has-children').on('click', function(event) {
event.preventDefault();
event.stopPropagation();
$(this).children('.sub-menu').slideToggle(500);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li>item 1</li>
<li class="has-children">item 2
<ul class="sub-menu">
<li>sub-item 1</li>
</ul>
</li>
<li class="has-children">item 3
<ul class="sub-menu">
<li>sub-item 1</li>
<li class="has-children">sub-item 2
<ul class="sub-menu">
<li>sub-sub-item 1</li>
</ul>
</li>
</ul>
</li>
</ul>
Related
I have 3 menus in a nav and each menu has a submenu. I need to do 2 acts when clicking on a menu, or plus/minus sign.
First Act: When I click:
show this submenu
change this plus sign to minus sign
Close other submenus
Change other submenus signs from minus to plus
Second Act: When I click on an element which has an open submenu, again
submenu will be closed.
minus sign change to plus sign
My JQuery is working as expected on the First Act, but somehow it doesn't work on the Second Act
Please give me a hand. Thanks
$(function(showHidesubMenu) {
$('.parent-list').click(function() {
$(this)
.toggleClass('open').next().toggleClass('icon-minus icon-plus')
.add($('.parent-list.open').not(this).removeClass('open').next().toggleClass('icon-minus icon-plus'))
.parent().next('.child-layer').toggleClass('show')
})
})
$(function() {
$('.plus-minus').click(function() {
$(this)
.prev().toggleClass('open')
.next().toggleClass('icon-minus icon-plus')
.add($('.parent-list.open').not(this).removeClass('open'))
.parent().next('.child-layer').toggleClass("show");
})
})
li {
display: flex
}
.icon-plus:before {
content: "\2795";
}
.icon-minus:before {
content: "\2212";
}
.parent-list {
padding-right: 50px;
cursor: pointer;
}
.collapse {
display: none;
}
.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<ul>
<li class="non-active">
<a class="non-active parent-list" href="#level1">level 1</a>
<div class="plus-minus icon-plus"> </div>
</li>
<ul class="child-layer collapse">
<li>Sub Child 1</li>
<li>Sub Child 1</li>
<li>Sub Child 1</li>
</ul>
<li class="non-active">
<a class="non-active parent-list" href="#level2">level 2</a>
<div class="plus-minus icon-plus"> </div>
</li>
<ul class="child-layer collapse">
<li>Sub Child 2</li>
<li>Sub Child 2</li>
<li>Sub Child 2</li>
</ul>
<li class="non-active">
<a class="non-active parent-list" href="#level3">level 3</a>
<div class="plus-minus icon-plus"> </div>
</li>
<ul class="child-layer collapse">
<li>Sub Child 3</li>
<li>Sub Child 3</li>
<li>Sub Child 3</li>
</ul>
</ul>
$(function(showHidesubMenu) {
$('.parent-list').click(function() {
$(this)
.toggleClass('opening') // add class mark this opening
.next()
.toggleClass('icon-minus icon-plus')
.add(
$('.parent-list.opening')
.not(this)
.removeClass('opening')
.next()
.toggleClass('icon-minus icon-plus')
)
// to parent toogle ul
.parent()
.next('.child-layer')
.toggleClass('show')
})
})
li {
display: flex
}
.icon-plus:before {
content: "\2795";
}
.icon-minus:before {
content: "\2212";
}
.parent-list {
padding-right: 50px;
cursor: pointer;
}
.collapse {
display: none;
}
.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<ul>
<li class="non-active">
<a class="non-active parent-list" href="#level1">level 1</a>
<div class="plus-minus icon-plus"> </div>
</li>
<ul class="child-layer collapse">
<li>Sub Child 1</li>
<li>Sub Child 1</li>
<li>Sub Child 1</li>
</ul>
<li class="non-active">
<a class="non-active parent-list" href="#level2">level 2</a>
<div class="plus-minus icon-plus"> </div>
</li>
<ul class="child-layer collapse">
<li>Sub Child 2</li>
<li>Sub Child 2</li>
<li>Sub Child 2</li>
</ul>
<li class="non-active">
<a class="non-active parent-list" href="#level3">level 3</a>
<div class="plus-minus icon-plus"> </div>
</li>
<ul class="child-layer collapse">
<li>Sub Child 3</li>
<li>Sub Child 3</li>
<li>Sub Child 3</li>
</ul>
</ul>
I know there are a lot of similar solutions.. This one almost works :)
I have an unsorted list:
<ul id="Tree" class="sub-menu">
<li class="folder">First level
<ul class="sub-menu">
<li>File 1.1</li>
<li class="folder">Second level
<ul class="sub-menu">
<li>File 2.1</li>
<li>File 2.2</li>
<li class="folder">Tretji nivo
<ul class="sub-menu">
<li>File 3.1</li>
<li>File 3.2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
And the jQuery:
$('.folder').click(function(event) {
event.stopPropagation();
$(this).find('>.sub-menu').slideToggle();
});
Click on .folder works as desired. The problem is that the slideToggle is triggered on all li elements. So if I click on a li > a element the file is downloaded but the ul is toggled also. I want to prevent toggle when I click on an element that has no direct ul child.
You could add the folder class to the level text instead of the whole li tag :
$('.folder').click(function(event) {
event.stopPropagation();
$(this).next('.sub-menu').slideToggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="Tree" class="sub-menu">
<li><span class="folder">First level</span>
<ul class="sub-menu">
<li>File 1.1</li>
<li><span class="folder">Second level</span>
<ul class="sub-menu">
<li>File 2.1</li>
<li>File 2.2</li>
<li><span class="folder">Tretji nivo</span>
<ul class="sub-menu">
<li>File 3.1</li>
<li>File 3.2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
I am creating a mobile menu as dropdown list items as follows,
jQuery('#menu-main-menu > .is-dropdown-submenu-parent a').click(function() {
$(this).siblings('ul').slideToggle(500);
jQuery(this)
.closest(".is-dropdown-submenu-parent")
.siblings()
.find(".sub-menu")
.slideUp();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main-menu-mobile" class="menu-list navbar-collapse collapse clearfix">
<ul id="menu-main-menu" class="navigation clearfix" style="display:flex; flex-direction: column">
<li data-toggle="collapse" class="dropdown is-dropdown-submenu-parent collapsed">
menu 1
<ul class="sub-menu ">
<li>sub menu 1</li>
<li>sub menu 2</li>
<li>sub menu 3</li>
<li>sub menu 4</li>
</ul>
</li>
<li data-toggle="collapse" class="dropdown is-dropdown-submenu-parent collapsed">
menu 2
<ul class="sub-menu">
<li>sub menu 1</li>
<li>sub menu 2</li>
<li>sub menu 3</li>
<li>sub menu 4</li>
</ul>
</li>
</ul>
</div>
The problem is when I click into the main menu for opening, it opens outside the frame of the menu (it gets outside the container) explain more: when I click on the menu1 the items of it appear above the menu2. Where it suppose to shift menu2 down and list the items bellow menu1.
I did not get where is the error & I have searched & seen all menus made as I did !!
Try this small change
I have commented slideUp() line in the .js.
I think it works as you want.
jQuery('#menu-main-menu > .is-dropdown-submenu-parent a').click(function() {
$(this).siblings('ul').slideToggle(500);
jQuery(this)
.closest(".is-dropdown-submenu-parent")
.siblings()
.find(".sub-menu")
//.slideUp(); // commented this line
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main-menu-mobile" class="menu-list navbar-collapse collapse clearfix">
<ul id="menu-main-menu" class="navigation clearfix" style="display:flex; flex-direction: column">
<li data-toggle="collapse" class="dropdown is-dropdown-submenu-parent collapsed">
menu 1
<ul class="sub-menu ">
<li>sub menu 1</li>
<li>sub menu 2</li>
<li>sub menu 3</li>
<li>sub menu 4</li>
</ul>
</li>
<li data-toggle="collapse" class="dropdown is-dropdown-submenu-parent collapsed">
menu 2
<ul class="sub-menu">
<li>sub menu 1</li>
<li>sub menu 2</li>
<li>sub menu 3</li>
<li>sub menu 4</li>
</ul>
</li>
</ul>
</div>
I am using Jasny Bootstrap for my responsive website. However, the links for the sub-navigations does not work on mobile. I am able to click into the links when I test it on my desktop. But when I test it on my phone, it only closes the navigation side bar. Following is my code:
<!--mobile nav-->
<nav id="mob-nav" class="navmenu navmenu-inverse navmenu-fixed-right offcanvas" role="navigation">
<ul class="nav navmenu-nav">
<li class="active"><span>Home</span></li>
<li class="dropdown"><span>Courses</span> <b class="caret"></b>
<ul class="dropdown-menu navmenu-nav" role="menu">
<li class="dropdown">Sub Nav 1</li>
<li class="divider"></li>
<li class="dropdown">Sub Nav 2</li>
<li class="divider"></li>
<li class="dropdown">Sub Nav 3</li>
<li class="divider"></li>
<li class="dropdown">Sub Nav 4</li>
</ul>
</li>
<li>Navigation 2</li>
<li>Navigation 3</li>
<li>Navigation 4</li>
<li>Navigation 5</li>
</ul>
</nav>
<!--end mobile nav-->
Could it be a case of clashing js?
Edit: I did some trial and error and found that the class "navmenu-nav" is causing the problem. But I am still unsure how I can debug this.
These are the only js attached:
<script src="js/1.11.0/jquery.min.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/jasny-bootstrap.js"></script>
<script src="js/readmore.js"></script>
Just found the answer!
Add: .navmenu-nav.dropdown-menu { position:relative; } to your CSS and like magic, it will work!
I am trying to write my article beside my vertical menu, but all my article going inside that menu. I want my menu to be fixed on that page on the left side and all my new articles or any pictures should come on after menu.
MY HTML
<nav id="wrapper-250">
<ul class="accordion">
<li id="one" class="files">
Health Beat
<ul class="sub-menu">
<li><em>01</em>Sub Menu 1
<ul class="sub-sub-menu">
<li><em>a</em>Sub Menu 2</li>
<li><em>b</em>Sub Menu 2</li>
<li><em>c</em>Sub Menu 2</li>
<li><em>d</em>Sub Menu 2</li>
<li><em>e</em>Sub Menu 2</li>
</ul>
</li>
<li><em>02</em>Sub Menu 1</li>
<li><em>03</em>Sub Menu 1</li>
<li><em>04</em>Sub Menu 1</li>
<li><em>05</em>Sub Menu 1</li>
</ul>
</li>
<li id="two" class="mail">
Mail
<ul class="sub-menu">
<li><em>01</em>Hotmail</li>
<li><em>02</em>Yahoo</li>
</ul>
</li>
<li id="three" class="cloud">
Cloud
<ul class="sub-menu">
<li><em>01</em>Connect</li>
<li><em>02</em>Profiles</li>
<li><em>03</em>Options</li>
<li><em>04</em>Connect</li>
<li><em>05</em>Profiles</li>
<li><em>06</em>Options</li>
</ul>
</li>
<li id="four" class="sign">
Sign Out
<ul class="sub-menu">
<li><em>01</em>Log Out</li>
<li><em>02</em>Delete Account</li>
<li><em>03</em>Freeze Account</li>
</ul>
</li>
</ul>
</nav>
<div id="body-part">
<p>
</P>
</div>
http://codepen.io/anon/pen/XbXbqQ
Add a big padding-left to your #body-part:
padding-left: 500px; /* example */
Demo here: http://jsfiddle.net/baLq1d1k/
Or you can do it using jquery if the width of your #wrapper-250 changes:
$("#body-part").css("padding-left", ($("#wrapper-250").width() + 10));