How to add side menu on hover - javascript

I want to add side menus to the sub-menus like PRODUCT 1, PRODUCT 2 etc. that appear on the side on hover over them. How do I do that on the following code?
This is the code that I have so far.
CSS:
#import url(http://fonts.googleapis.com/css?family=Open+Sans:400, 600, 300);
#charset"UTF-8";
/* Base Styles */
#cssmenu, #cssmenu ul, #cssmenu li, #cssmenu a {
margin: 0;
padding: 0;
border: 0;
list-style: none;
font-weight: normal;
text-decoration: none;
line-height: 1;
font-family:'Open Sans', sans-serif;
font-size: 14px;
position: relative;
}
#cssmenu a {
line-height: 1.3;
}
#cssmenu {
width: 300px;
margin-left: 90px;
background: #A3FFFF;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 3px;
padding: 3px;
-moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.6);
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.6);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.6);
}
#cssmenu > ul > li {
margin: 0 0 3px 0;
}
#cssmenu > ul > li:last-child {
margin: 0;
}
#cssmenu > ul > li > a {
font-size: 15px;
display: block;
color: #ffffff;
text-shadow: 0 1px 1px #000;
background: #A3FFFF;
background: -moz-linear-gradient(#565656 0%, #323232 100%);
background: -webkit-gradient (linear, left top, left bottom, color-stop(0%, #565656), color-stop(100%, #323232));
background: -webkit-linear-gradient(#565656 0%, #323232 100%);
background: linear-gradient(#565656 0%, #323232 100%);
border: 1px solid #000;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
#cssmenu > ul > li > a > span {
display: block;
border: 1px solid #666666;
padding: 6px 10px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
font-weight: bold;
}
#cssmenu > ul > li > a:hover {
text-decoration: none;
font-weight: bold;
}
#cssmenu > ul > li.active {
border-bottom: none;
}
#cssmenu > ul > li.active > a {
background: #47A3FF;
background: -moz-linear-gradient(#47A3FF 0%, #47A3FF 100%);
background: -webkit-gradient (linear, left top, left bottom, color-stop(0%, #47A3FF), color-stop(100%, #47A3FF));
background: -webkit-linear-gradient(#47A3FF 0%, #47A3FF 100%);
background: linear-gradient(#47A3FF 0%, #47A3FF 100%);
color: #fff;
text-shadow: 0 1px 1px #fff;
border: 1px solid #47A3FF;
}
#cssmenu > ul > li.active > a span {
border: 1px solid #47A3FF;
}
#cssmenu > ul > li.has-sub > a span {
background: url(images/icon_plus.png) 98% center no-repeat;
}
#cssmenu > ul > li.has -sub.active > a span {
background: url(images/icon_minus.png) 98% center no-repeat;
}
/* Sub menu */
#cssmenu ul ul {
padding: 5px 12px;
display: none;
}
#cssmenu ul ul li {
padding: 3px 0;
}
#cssmenu ul ul a {
display: block;
color: #191975;
font-size: 13px;
font-weight: bold;
}
#cssmenu ul ul a:hover {
color: cornflowerblue;
font-weight:bold;
}
JS:
(function ($) {
$(document).ready(function () {
$('#cssmenu > ul > li > a').click(function () {
$('#cssmenu li').removeClass('active');
$(this).closest('li').addClass('active');
var checkElement = $(this).next();
if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
$(this).closest('li').removeClass('active');
checkElement.slideUp('normal');
}
if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
$('#cssmenu ul ul:visible').slideUp('normal');
checkElement.slideDown('normal');
}
if ($(this).closest('li').find('ul').children().length == 0) {
return true;
} else {
return false;
}
});
});
})(jQuery);
HTML:
<div id='cssmenu'>
<ul>
<li class='has-sub'>
<a href='#'><span>CENTRAL COMPLIANCE</span></a>
<ul>
<li><a href='#'><span>PRODUCT 1</span></a></li>
<hr>
<li><a href='#'><span>PRODUCT 2</span></a></li>
<hr>
<li><a href='#'><span>PRODUCT 3</span></a></li>
<hr>
<li><a href='#'><span>PRODUCT 4</span></a></li>
<hr>
<li><a href='#'><span>GEPOC</span></a></li>
<hr>
<li><a href='#'><span>Global Registration</span></a></li>
<hr>
<li><a href='#'><span>MBL</span></a></li>
<hr>
<li><a href='#'><span>Account Affirmations</span></a></li>
<hr>
<li class='last'><a href='#'><span>Outside Affiliations</span></a></li>
</ul>
</li>
<li class='has-sub'>
<a href='#'><span>CONTROL ROOM</span></a>
<ul>
<li><a href='#'><span>CDS</span></a></li>
<hr>
<li><a href='#'><span>UK Registration</span></a></li>
<hr>
<li class='last'><a href='#'><span>Compliance Portal</span></a></li>
</ul>
</li>
<li class='has-sub'>
<a href='#'><span>LARGE HOLDINGS</span></a>
<ul>
<li class='last'><a href='#'><span>LHO</span></a></li>
</ul>
</li>
<li class='has-sub'>
<a href='#'><span>ORCHESTRIA</span></a>
<ul>
<li class='last'><a href='#'><span>Orchestria</span></a></li>
</ul>
</li>
</ul>
</div>
Please help me edit this code. Thanks.

The css attribute :hover should work well. Begin with a div that has a display of none. Then on hover of product 1, for example, change to display block.
.side-menu {
display:none;
}
.product1:hover > .side-menu {
display:block;
}
It is important to note that this only works if the menu item that is to be hidden and shown is a child of the the item you are hovering over. That shouldn't be an issue for you.
Edit for Clarification:
In your HTML add the ul that will hold your side menu. Assign a class to the ul. This is how you create a nested list. Also add a class to the li product 1 so that we can select it.
<li>Product1</li>
<ul class="side-menu">
<li>first sub menu item</ul>
</ul>
</li>
Now your css. It will be the same as what I wrote above because I used the same class names. What happens is when the page loads the side menu will be hidden because the display is set to none. When you :hover over the html element with a class of 'product1' it changes the display attribute of the side menu from none to block.
You will still need to position the new menu item appropriately.

Related

Show menu sub-elements on hover using jQuery [duplicate]

This question already has answers here:
Show submenu's submenu on submenu hover only
(3 answers)
Closed 4 years ago.
I created an HTML page with a navigation menu in a sidebar. Some of the menu element contain sub-elements. What I am trying to do is:
Hide all sub-elements (this I managed)
If I hover over an element that has sub-element, show the sub-elements.
If I hover over an element that does not have any sub-elements, don't do anything.
I sort of know how to do this with CSS, but since this is for a jQuery class, I want to use jQuery.
I already found a few hints on the web, but I don't really know how to apply the suggestions to my code. I am completey new to jQuery, hence any help will be much appreciated!
Here's the HTML:
<nav>
<ul class="menu">
<li>Home</li>
<li>Page 1</li>
<li>Page 2
<ul class="submenu">
<li>Subpage 2a</li>
<li>Subpage 2b</li>
<li>Subpage 2c</li>
</ul>
</li>
<li>Page 3</li>
</ul>
</nav>
CSS:
nav {
float: left;
width: 200 px;
position: fixed;
top: 80px;
left: 10px;
border-top: 1px solid #9AA2B2;
border-right: 1px solid #9AA2B2;
border-left: 1px solid #9AA2B2;
}
.menu, .submenu {
list-style: none;
padding: 0;
margin: 0;
}
.menu a {
display: block;
padding: 10px 15px;
background: linear-gradient(to bottom, #7d7e7d 0%,#6B737E 100%);
border-top: 1px solid #9AA2B2;
border-bottom: 1px solid #2E323A;
text-decoration: none;
color: white;
}
.menu a:hover {
background: linear-gradient(to bottom, #3EB9E7 0%,#8abbd7 100%);
}
.submenu a {
padding: 10px 25px;
background: linear-gradient(to bottom, #E2E2E2 0%,#fcfff4 100%);
border-bottom: 1px solid #CFD0CF;
color: black;
}
.submenu a:hover {
background: linear-gradient(to bottom, #C5C6C5 0%,#d6dbbf 100%);
background-color: #C5C6C5;
}
.submenu {
overflow: hidden;
max-height: 0;
}
This is a jQuery snippet that I found and that seems to make sense, but I am not sure how to apply it.
$(document).ready(function () {
$('#nav > li > a').hover(function(){
if ($(this).attr('class') != 'deployed'){
$('#nav li ul').slideUp();
$(this).next().slideToggle();
$('#nav li a').removeClass('deployed');
$(this).addClass('deployed');
}
});
});
If you want to only use jQuery to achieve this. This is how you can do it.
$(document).ready(function() {
$('.menu > li').hover(function() {
$(this).has('.submenu').children('.submenu').stop().slideToggle();
});
});
So what the above code does is that on hover, it checks if the hovered element has a children with a class '.submenu' and if it does, then it selects that children and toggles it with a sliding effect. Instead of slide toggling it you could obviously do anything with it like adding a class.
The .stop() stops repetition of the sliding effect if you were to quickly toggle hover on and off several times.
I fixed below then the sample works like below snippet (for demo purpose, remove position:fixed from ):
1. bind hover event to $('nav > ul > li > a') intead of $('#nav > li > a'), but it slideDown the sub menu when the mouse hover on the sub menu, so need to change it to $('nav > ul > li')
2. replace max-height:0 with display:none; Below is the reason using display instead of max-height.
Check JQuery API:
As JQuery Defined:
The .slideToggle() method animates the height of the matched elements.
This causes lower parts of the page to slide up or down, appearing to
reveal or conceal the items. If the element is initially displayed, it
will be hidden; if hidden, it will be shown. The display property is
saved and restored as needed. If an element has a display value of
inline, then is hidden and shown, it will once again be displayed
inline. When the height reaches 0 after a hiding animation, the
display style property is set to none to ensure that the element no
longer affects the layout of the page.
3. in the handler of hover bind, execute $('ul', $(this)).slideToggle( "slow" );
$(document).ready(function () {
$('nav > ul > li').hover(function(){
$('ul', $(this)).slideToggle( "slow" );
});
});
nav {
float: left;
width: 200 px;
top: 80px;
left: 10px;
border-top: 1px solid #9AA2B2;
border-right: 1px solid #9AA2B2;
border-left: 1px solid #9AA2B2;
}
.menu, .submenu {
list-style: none;
padding: 0;
margin: 0;
}
.menu a {
display: block;
padding: 10px 15px;
background: linear-gradient(to bottom, #7d7e7d 0%,#6B737E 100%);
border-top: 1px solid #9AA2B2;
border-bottom: 1px solid #2E323A;
text-decoration: none;
color: white;
}
.menu a:hover {
background: linear-gradient(to bottom, #3EB9E7 0%,#8abbd7 100%);
}
.submenu a {
padding: 10px 25px;
background: linear-gradient(to bottom, #E2E2E2 0%,#fcfff4 100%);
border-bottom: 1px solid #CFD0CF;
color: black;
}
.submenu a:hover {
background: linear-gradient(to bottom, #C5C6C5 0%,#d6dbbf 100%);
background-color: #C5C6C5;
}
.submenu {
overflow: hidden;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul class="menu">
<li>Home</li>
<li>Page 1</li>
<li>Page 2
<ul class="submenu">
<li>Subpage 2a</li>
<li>Subpage 2b</li>
<li>Subpage 2c</li>
</ul>
</li>
<li>Page 3</li>
</ul>
</nav>
We add const subMenu = $(this).find('.submenu'); to find .submenu element with .menu > li selector.
Then we add our logic to toggle class via addClass and removeClass. I have also included second callback for .hover, which is hoverout.
$(selector).hover(hoverInCallback, hoverOutCallback);
Since I did not want to mess your css I have added only following rule
.submenu.visible {
overflow: initial;
max-height: auto;
}
Hope this helps!
Here is working example.
$(document).ready(function () {
$('.menu > li').hover(function() {
const subMenu = $(this).find('.submenu');
subMenu.addClass('visible');
},
// hoverout
function() {
const subMenu = $(this).find('.submenu');
subMenu.removeClass('visible');
});
});
nav {
float: left;
width: 200 px;
position: fixed;
top: 80px;
left: 10px;
border-top: 1px solid #9AA2B2;
border-right: 1px solid #9AA2B2;
border-left: 1px solid #9AA2B2;
}
.menu, .submenu {
list-style: none;
padding: 0;
margin: 0;
}
.menu a {
display: block;
padding: 10px 15px;
background: linear-gradient(to bottom, #7d7e7d 0%,#6B737E 100%);
border-top: 1px solid #9AA2B2;
border-bottom: 1px solid #2E323A;
text-decoration: none;
color: white;
}
.menu a:hover {
background: linear-gradient(to bottom, #3EB9E7 0%,#8abbd7 100%);
}
.submenu a {
padding: 10px 25px;
background: linear-gradient(to bottom, #E2E2E2 0%,#fcfff4 100%);
border-bottom: 1px solid #CFD0CF;
color: black;
}
.submenu a:hover {
background: linear-gradient(to bottom, #C5C6C5 0%,#d6dbbf 100%);
background-color: #C5C6C5;
}
.submenu {
overflow: hidden;
max-height: 0;
}
.submenu.visible {
overflow: initial;
max-height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul class="menu">
<li>Home</li>
<li>Page 1</li>
<li>Page 2
<ul class="submenu">
<li>Subpage 2a</li>
<li>Subpage 2b</li>
<li>Subpage 2c</li>
</ul>
</li>
<li>Page 3</li>
</ul>
</nav>
You just need to make a few adjustments to your code, mostly targeting, but also a minor CSS change.
Change #nav to .menu in all jQuery code so that the correct elements are targeted.
Change max-height: 0; to display: none; in the .submenu CSS so your submenu can be shown . You can also set a min-width for your menu so the width doesn't change when the submenu is visible.
You may also choose to modify your jQuery code or add a mouseout handler so the submenu is hidden when you are no longer over the parent/submenu.
See this fiddle: https://jsfiddle.net/vbryo27z/9/
To actually answer your question unlike these others... Basically add a mouseenter event handler, check if the li has a submenu, if so add the active class to it.
Modify it to how you want them to close
$('.menu li').mouseenter(function() {
if($(this).has('.submenu')) {
$(this).find('.submenu').addClass('active');
}
});
$('.menu .submenu').mouseleave(function() {
$('.submenu').removeClass('active');
});
nav {
float: left;
width: 200 px;
position: fixed;
top: 80px;
left: 10px;
border-top: 1px solid #9AA2B2;
border-right: 1px solid #9AA2B2;
border-left: 1px solid #9AA2B2;
}
.menu, .submenu {
list-style: none;
padding: 0;
margin: 0;
}
.menu a {
display: block;
padding: 10px 15px;
background: linear-gradient(to bottom, #7d7e7d 0%,#6B737E 100%);
border-top: 1px solid #9AA2B2;
border-bottom: 1px solid #2E323A;
text-decoration: none;
color: white;
}
.menu a:hover {
background: linear-gradient(to bottom, #3EB9E7 0%,#8abbd7 100%);
}
.submenu a {
padding: 10px 25px;
background: linear-gradient(to bottom, #E2E2E2 0%,#fcfff4 100%);
border-bottom: 1px solid #CFD0CF;
color: black;
}
.submenu a:hover {
background: linear-gradient(to bottom, #C5C6C5 0%,#d6dbbf 100%);
background-color: #C5C6C5;
}
.submenu {
overflow: hidden;
max-height: 0;
transition: 0.3s ease;
}
.submenu.active {
max-height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul class="menu">
<li>Home</li>
<li>Page 1</li>
<li>Page 2
<ul class="submenu">
<li>Subpage 2a</li>
<li>Subpage 2b</li>
<li>Subpage 2c</li>
</ul>
</li>
<li>Page 3</li>
</ul>
</nav>

Why is the sub-menu in this accordion menu not staying open?

I adapted a menu from CSS MenuMaker, and I've been hunting for why it behaves differently. It is here. When you click on the menu item, the sub-menu opens, but if the mouse remains over the clicked menu item, the rest doesn't move down to make room, and the sub-menu doesn't use the styling it is supposed to. Instead it uses the styling of a top-level menu item.
HTML
<div class="col-2 col-m-2 accordian darkYellow roundLeft">
<p class="title">Melt-in-Place Station (MIP)
</p>
<ul>
<li class="has-sub"><a><span>Reference Docs</span></a>
<ul>
<li><a href="http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20150000305.pdf">
<span>Melted regolith construction</span></a></li>
</ul>
</li>
<li class="has-sub"><a><span>Forum Threads</span></a></li>
<li class="has-sub"><a><span>Models</span></a></li>
</ul>
</div>
CSS
.accordian,
.accordian ul,
.accordian li,
.accordian a {
margin: 0;
padding: 0;
border: 0;
list-style: none;
text-decoration: none;
line-height: 1;
font-size: 1em;
position: relative;
color: yellow;
}
p.title {
font-weight: 600;
padding: 16px 6px;
}
.accordian a {
line-height: 1.3;
cursor: pointer;
}
.accordian {
font-weight: 400;
color: rgba(255, 255, 0, 1);
text-align: right;
}
.accordian > ul > li {
margin: 0 0 2px 0;
}
.accordian > ul > li:last-child {
margin: 0;
}
.accordian > ul > li > a {
font-size: 1.1em;
display: block;
background: rgba(50, 50, 50, 0.6);
}
.accordian > ul > li > a > span {
display: block;
padding: 6px 10px;
}
.accordian > ul > li > a:hover {
text-decoration: none;
}
.accordian > ul > li.active {
border-bottom: none;
}
.accordian > ul > li.active > a {
background: #333;
}
.accordian > ul > li.has-sub > a span {
background: url(http://www.moonwards.com/img/iconPlus.png) no-repeat left center;
}
.accordian > ul > li.has-sub.active > a span {
background: url(http://www.moonwards.com/img/iconMinus.png) no-repeat left center;
}
/* Sub menu */
.accordian ul ul {
padding: 5px 12px;
display: none;
}
.accordian ul ul li {
padding: 3px 0;
}
.accordian ul ul a {
display: block;
font-size: 0.9em;
font-weight: 400italic;
}
jQuery
( function( $ ) {
$( document ).ready(function() {
$('.accordian > ul > li > a').click(function() {
$('.accordian li').removeClass('active');
$(this).closest('li').addClass('active');
var checkElement = $(this).next();
if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
$(this).closest('li').removeClass('active');
checkElement.slideUp('normal');
}
if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
$('.accordian ul ul:visible').slideUp('normal');
checkElement.slideDown('normal');
}
if($(this).closest('li').find('ul').children().length == 0) {
return true;
} else {
return false;
}
});
});
} )( jQuery );
I assume this is some dumb thing, but any help appreciated.
After inspecting I think I found the culprit. Try edit your CSS like this:
li:hover ul {
display: block;
position: relative; /* relative, not absolute */
top: 100%;
left: -10px;
background-color: rgba(50, 50, 0, 1);
font-size: 13px;
}
Your problem is not entirely CSS. I just figured out that the LI's height is covering the dropdown. However, if you reduce the height of the LI, the next LI doesn't open the amount it needs to. A quick patch would be to apply this CSS below however, I would much rather get the JQuery guys here to help you out.
.accordian ul ul {
padding: 5px 12px;
display: none;
margin-top: 0px;
z-index: 99999;
position: relative;
background: none;
}
p.s. This solves the problem you asked, but you need to tweak the font and size so that there is no difference

why can't I highlight the link i am currently on?

What I basically has a side bar navigation with a couple of links. I want to be able to highlight the appropriate link according to the page I am on.
for some reasons, my code doesn't seem to be working.
here's the html file:
<div class='sidebar'>
<div class='title'>
Sonder
</div>
<ul class='nav'>
<li><a class='active' href='members.php?view = <?=$user?>'>Home</a></li>
<li><a href='members.php' >Members</a></li>
<li><a href='friends.php' >Friends</a></li>
<li><a href='messages.php'>Messages</a></li>
<li><a href='profile.php'>Edit Profile</a></li>
<li><a href='logout.php'>Logout</a></li>
</ul>
</div>
here's a part of the css:
.nav li a {
position: relative;
display: block;
padding: 15px 15px 15px 50px;
font-size: 12px;
color: #eee;
border-bottom: 1px solid #222;
cursor: pointer;
}
.nav li a:before {
font: 14px fontawesome;
position: absolute;
top: 14px;
left: 20px;
}
.nav li:nth-child(1) a:before {
content: '\f015';
}
.nav li:nth-child(2) a:before {
content: '\f0c2';
}
.nav li:nth-child(3) a:before {
content: '\f183';
left: 23px;
}
.nav li:nth-child(4) a:before {
content: '\f003';
}
.nav li:nth-child(5) a:before {
content: '\f013';
}
.nav li:nth-child(6) a:before {
content: '\f023';
left: 22px;
}
.nav li a:hover {
background: #444;
}
.nav li a.active {
box-shadow: inset 5px 0 0 #5b5, inset 6px 0 0 #222;
background: #444;
}
here's the javascript code:
$(document).ready(function() {
setNavigation();
});
function setNavigation() {
var path = window.location.pathname;
path = path.replace(/\/$/, "");
path = decodeURIComponent(path);
$(".nav a").each(function () {
var href = $(this).attr('href');
if (path.substring(0, href.length) === href) {
$(this).closest('li').addClass('active');
}
});
}
There are a couple of issues in your code.
The path JS variable is having a preceding forward slash, i.e. /members.php or /friends.php. For this reason, the path.substring(0, href.length) part is returning like /members.ph which doesn't match with any hrefs in the page.
The active class that highlights the menu, is on the anchor tag element, not in the li tag element as per the CSS you wrote, but with the JS you tried to add the active class to the li.
Here is a complete snippet that worked:
HTML:
<div class='sidebar'>
<div class='title'>Sonder</div>
<ul class='nav'>
<li><a class='active' href='members.php?view=<?=!empty($user)?:0?>'>Home</a></li>
<li><a href='members.php' >Members</a></li>
<li><a href='friends.php' >Friends</a></li>
<li><a href='messages.php'>Messages</a></li>
<li><a href='profile.php'>Edit Profile</a></li>
<li><a href='logout.php'>Logout</a></li>
</ul>
</div>
CSS:
.nav li a {
position: relative;
display: block;
padding: 15px 15px 15px 50px;
font-size: 12px;
color: #eee;
border-bottom: 1px solid #222;
cursor: pointer;
}
.nav li a:before {
font: 14px fontawesome;
position: absolute;
top: 14px;
left: 20px;
}
.nav li:nth-child(1) a:before {
content: '\f015';
}
.nav li:nth-child(2) a:before {
content: '\f0c2';
}
.nav li:nth-child(3) a:before {
content: '\f183';
left: 23px;
}
.nav li:nth-child(4) a:before {
content: '\f003';
}
.nav li:nth-child(5) a:before {
content: '\f013';
}
.nav li:nth-child(6) a:before {
content: '\f023';
left: 22px;
}
.nav li a:hover {
background: #444;
}
.nav li a.active {
box-shadow: inset 5px 0 0 #5b5, inset 6px 0 0 #222;
background: #444;
}
Script Block:
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
setNavigation();
});
function setNavigation() {
var path = window.location.pathname;
path = path.replace(/\/$/, "");
path = decodeURIComponent(path);
$(".nav a").each(function () {
var href = $(this).attr('href');
if (path.substring(1, path.length) === href) {
$(".nav a").removeClass('active');
$(this).addClass('active');
return;
}
});
}
</script>
This should work properly.
I moved your code around a bit and made the jquery work, not sure how well it will work in the snippet so here's a fiddle https://jsfiddle.net/link2twenty/wysh0j6q/
$('document').ready(function() {
setNavigation();
});
function setNavigation() {
var path = window.location.href;
path = (path.substring(path.lastIndexOf('/') + 1));
$(".nav .menu").each(function() {
var href = $(this).attr('href');
if (path === href) {
$(this).addClass('active');
}
})
}
body {
margin: 0;
}
li {
list-style: none;
}
.nav li a {
position: relative;
display: block;
padding: 15px 15px 15px 50px;
font-size: 12px;
color: #eee;
background: #333;
border-bottom: 1px solid #222;
cursor: pointer;
}
.nav li a:before {
font: 14px fontawesome;
position: absolute;
top: 14px;
left: 20px;
}
.nav li:nth-child(1) a:before {
content: '\f015';
}
.nav li:nth-child(2) a:before {
content: '\f0c2';
}
.nav li:nth-child(3) a:before {
content: '\f183';
left: 23px;
}
.nav li:nth-child(4) a:before {
content: '\f003';
}
.nav li:nth-child(5) a:before {
content: '\f013';
}
.nav li:nth-child(6) a:before {
content: '\f023';
left: 22px;
}
.nav li a:hover {
background: #444;
}
.nav li a.active {
box-shadow: inset 5px 0 0 #5b5, inset 6px 0 0 #222;
background: #444;
}
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<script type='text/javascript' src='//code.jquery.com/jquery-2.1.4.js'></script>
<div class='sidebar'>
<div class='title'>
Sonder
</div>
<div class='nav'>
<li><a class='menu' href='#'>Home</a></li>
<li><a class='menu' href='#'>Members</a></li>
<li><a class='menu' href='#'>Friends</a></li>
<li><a class='menu' href='#'>Messages</a></li>
<li><a class='menu' href='js'>Edit Profile</a></li>
<li><a class='menu' href='#'>Logout</a></li>
</div>
</div>
Your CSS rules are executed on order, your active class overrides the hover.
Change position and it should work
.nav li a.active {
box-shadow: inset 5px 0 0 #5b5, inset 6px 0 0 #222;
background: #444;
}
.nav li a:hover {
background: #444;
}
Or add a specific active:hover rule
Change css rule to
.nav li.active a{}

Jquery slideUp doesn't work at first click

I've created myself a accordion menu, but I've got a problem. When I click for the first time on 'li' element slideUp doesn't work.
$(document).ready(function() {
$('#menu ul li a').click(function(e) {
e.preventDefault();
if ($(this).parent().hasClass('active')) {
if ($(this).next().is(':visible')) {
$(this).next().slideUp();
$(this).parent().removeClass('active');
} else {
$(this).next().slideDown();
}
} else {
$('#menu ul li').each(function() {
$(this).removeClass('active');
});
$('#menu ul li ul').slideUp();
$(this).next().slideDown();
$(this).parent().addClass('active');
}
});
});
#menu,
#menu ul,
#menu li,
#menu a {
margin: 0;
padding: 0;
border: 0;
list-style: none;
font-weight: normal;
text-decoration: none;
line-height: 1;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
position: relative;
}
#menu a {
line-height: 1.3;
}
#menu > ul > li {
margin: 0;
}
#menu > ul > li:last-child {
margin: 0;
}
#menu > ul > li > a {
font-size: 15px;
display: block;
color: #ffffff;
text-shadow: 0 1px 1px #000;
padding: 5px;
}
#menu > ul > li > a > span {
display: block;
padding: 6px 10px;
font-weight: bold;
}
#menu > ul > li > a:hover {
text-decoration: none;
background: #0074a2 url('../img/icons/menuActive.png') no-repeat 101%;
}
#menu > ul > li.active {
border-bottom: none;
}
#menu > ul > li.active > a {
background: #0074a2 url('../img/icons/menuActive.png') no-repeat 101%;
color: #fff;
text-shadow: 0 1px 1px #000;
}
/* Sub menu */
#menu ul ul {
padding: 5px 12px;
display: none;
background: #333333;
}
#menu ul ul li {
padding: 3px 0;
}
#menu ul ul a {
display: block;
color: #fff;
font-size: 13px;
font-weight: bold;
padding: 10px 0;
}
#menu ul ul a:hover {
color: #0074a2;
}
#menu ul li.active ul {
display: block;
}
#menu ul li img {
float: left;
margin: -2px 4px 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu">
<ul>
<li class='has-sub active'><a href='#'><span>AAA</span></a>
<ul>
<li><a href='#'><span>AAA_1</span></a></li>
<li><a href='#'><span>AAA_2</span></a></li>
<li><a href='#'><span>AAA_3</span></a></li>
</ul>
</li>
<li class='has-sub'><a href='#'><span>BBB</span></a>
<ul>
<li><a href='#'><span>BBB_1</span></a></li>
<li><a href='#'><span>BBB_2</span></a></li>
</ul>
</li>
<li class='has-sub last'><a href='#'><span>CCC</span></a>
<ul>
<li><a href='#'><span>CCC_1</span></a></li>
<li><a href='#'><span>CCC_2</span></a></li>
<li><a href='#'><span>CCC_3</span></a></li>
<li><a href='#'><span>CCC_4</span></a></li>
</ul>
</li>
</ul>
</div>
Here is my simple code typed in jsfiddle.
jsfiddle
Could anyone tell me where is an error and how to solve it ?
Thanks !
The state of the html goes like this:
1. From start: <ul>
2. After you click once: <ul style="display: none;">
3. After you click it again: <ul style="display: block;">
Now I'm not that great when it comes to css, but if you keep track of the dynamic css which goes on when you press it, then you'll know what attributes you are missing on your styling.
The problem is active class has been removed before finishing slideUp animation. Use setTimeout function like following.
setTimeout(function(){
$(this).parent().removeClass('active')
}, 0);
You can increase time if you need.
Update:
I think your selector should be.
$('#menu > ul > li > a')
instead of
$('#menu ul li a')

How to make a dynamic accordion menu with jQuery

Lets say I have the following menu structure. I have 3 problems with it.
$('.parent ul').hide();
var current_parent;
$(document).delegate('.parent', 'click', (function() {
var $this = $(this);
if(current_parent !== undefined) {
current_parent.find('ul').slideUp();
}
current_parent = $this;
// Check if the element is visble or not
if(!$this.find('ul').is(':visible')) {
$this.find('ul').slideDown();
} else {
$this.find('ul').slideUp();
}
}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li class="parent">menu item1
<ul>
<li class="child">Sub menu item1</li>
<li class="child parent">Sub menu item2
<ul>
<li class="child">Sub-sub menu item1</li>
</ul>
</li>
</ul>
</li>
<li class="parent">menu item2
<ul>
<li class="child">Sub menu item3</li>
</ul>
</li>
</ul>
When you click on menu item 1 the Sub-sub menu item1 is also
opened. How can this be prefented?;
When you click on Sub menu item2 the menu item1 is also closed. How can this be prefented?.
How can I make this more dynamic so that when I add deeper menu items the menu still works but without having to add things like: $('ul ul ul').slideDown(); etc.?
Could anyone help me with these problems?
Thanks in advance
You can create a drop drop down menu with jquery
I have given individual HTML, CSS and JQuery code, use it and try to understand it.
There is an outer <div id="navigation"> and inside it their is annow in it everyis main menu item andin everyis sub menu item. Furthermore you can create sub menu in sub menu also by creatingin`.
$(document).ready(function () {
$("li").click(function () {
var x = $(this).children("a:first").attr("href");
if (x != undefined)
window.location.href = x;
});
$("#nav li").hover(function () {
$(this).find("ul:first").css({
visibility: "visible",
display: "none",
}).slideDown(400);
}, function () {
$(this).find("ul:first").css({ visibility: "hidden" });
});
});
body {
font-family: Calibri, Verdana;
font-size: 16px;
color: white;
}
a {
color: inherit;
text-decoration: none;
}
#navigation {
height: 40px;
}
#nav {
list-style: none;
margin: 0px;
padding: 0px;
}
#nav ul {
list-style: none;
margin: 10px 0px 0px -5px;
padding: 0px;
display: none;
}
#nav li {
float: left;
width: 150px;
height: 30px;
padding: 10px 0px 0px 5px;
border: 0px solid transparent;
border-right-width: 1px;
border-right-color: gray;
background-color: #6397CB;
}
#nav li ul li {
width: 145px;
height: 22px;
padding: 10px 0px 8px 10px;
border: 0px solid transparent;
border-top-width: 1px;
border-top-color: gray;
}
#nav li ul li ul {
position: relative;
top: -40px;
margin-left: 145px;
color: white;
}
#nav li ul li ul li {
border: 0px solid transparent;
border-left-width: 1px;
border-left-color: gray;
border-top-width: 1px;
border-top-color: gray;
}
#nav li:hover {
background-color: lightgray;
cursor: pointer;
}
#nav li ul li:hover {
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navigation">
<ul id="nav">
<li>My Name</li>
<li>About U
<ul>
<li>How U?
<ul>
<li>Your Extras</li>
</ul>
</li>
<li>Howz U?</li>
</ul>
</li>
<li>More</li>
</ul>
</div>

Categories

Resources