Nested UL Height - javascript

I have a menu with nested UL's to work as a drop down menu. In the drop down I have another nested UL with LI's that are pragmatically generated so I don't know how many are going to be in their.
I was trying to set the height of the second UL on load so that I can put a border around the dropdown.
HTML:
<ul>
<li>1</li>
<li>2
<ul>
<li>2a
<ul class="submenu">
<li>2a1</li>
<li>2a2</li>
<li>2a3</li>
<li>2a4</li>
<li>2a5</li>
</ul>
</li>
<li>2b
<ul class="submenu">
<li>2b1</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
</ul>
</li>
</ul>
</li>
<li>3</li>
</ul>
CSS:
ul {
list-style-type: none;
}
ul li {
display: inline-block;
/*float: left;*/
width: 100px;
}
ul li:hover {
background-color: #cc0505;
color: white;
}
ul li ul {
/*visibility: hidden;*/
position: absolute;
padding: 0px;
border: 2px solid black;
/*min-height:120px;*/
}
ul li:hover ul {
visibility: visible;
}
ul li ul li {
/*display: inline;
float: left;*/
color: black;
}
ul li ul li:hover {
background-color: white;
color: black;
}
ul li ul li ul {
border: none;
min-height:0px;
}
ul li ul li ul li {
display: block;
/*float: none;*/
}
ul li ul li ul li:hover {
background-color: #cc0505;
color: white;
}
I have tried using $('ul ul ul').each and $('ul ul ul').next() to loop through any UL on the third level but it only seems to be picking up the first occurrence.
A jsfiddle I set up with my code and a few attempts I have made to get this right. http://jsfiddle.net/kZ236/2/

the problem is, that height() always takes the height of the first element of the set, no matter what you do before calling that.
using each() together with a Math.max will work
http://jsfiddle.net/kZ236/3/
your code with next() didn't work as the ul didn't had a next element. next() is no iterator through the set of $('ul ul ul') but getting the next sibbling in the dom tree.

Try this:
$(document).ready(function () {
$('#nav>li>ul').each(function(){
var maxHt=0;
$(this).find('.submenu').each(function(){
var bottomPosition=$(this).height() +$(this).position().top
maxHt= bottomPosition>maxHt ? bottomPosition : maxHt;
});
$(this).height( maxHt)
})
})
DEMO

Related

jQuery .hover() or .mouseleave() not working on chrome

Problem description:
In my menu when .mouseenter() the menu opens and when .mouseleave() it closes, but if i click a lot , the .mouseleave() event is executed.
This only happened on chrome browser.
I have other .click() events inside my menu, but every click I made, the .mouseleave() event is execute.
$(document).ready(function() {
$("#nav1 li").hover(
function() {
$(this).find('ul').slideDown();
},
function() {
$(this).find('ul').slideUp();
});
});
#nav1 a {
color: #FFFFFF;
}
#nav1 li ul li a:hover {
background-color: #394963;
}
div ul li ul {
background-color: #4a5b78;
list-style: none
}
#nav1 > li > a {
padding: 16px 18px;
display: block;
border-bottom: 2px solid #212121;
}
#nav1 li ul li a {
padding: 10px 0;
}
div {
background-color: #000000;
background-color: #343434;
width: 280px;
}
/* Hide Dropdowns by Default */
#nav1 li ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul id="nav1">
<li>Hover here and infinite click
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 2
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
</ul>
<div>
Try click "Hover here and infinite click" to see this problem.
EDIT:
As you guys said, the problem occurs in this example.
Here is a video: Video link
When you click many times the browser has lost the element reference, try this example:
<div id="container">
<ul id="nav1">
<li>Menu Heading 1
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 2
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 3
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
</ul>
<div>
Css
ul,
li,
a {
padding: 0px;
margin: 0px;
}
.show {
display: block !important;
}
#nav1 a {
color: #FFFFFF;
}
#nav1 li ul li a:hover {
background-color: #394963;
}
div ul li ul {
background-color: #4a5b78;
list-style: none
}
#nav1 > li > a {
background-color: #343434;
padding: 16px 18px;
text-decoration: none;
display: block;
border-bottom: 2px solid #212121;
background: linear-gradient(top, #343434, #111111);
}
#nav1 li ul li a {
padding: 10px 0;
padding-left: 30px;
text-decoration: none;
display: block;
}
div {
background-color: #000000;
background-color: #343434;
width: 280px;
}
/* Hide Dropdowns by Default */
#nav1 li ul {
display: none;
}
JS
$(document).ready(function() {
$("#nav1 li").hover(
function(e) {
let ulMenu = $(this).find('ul');
ulMenu.addClass('show');
//$(this).find('ul').slideDown();
},
function(e) {
if(e.relatedTarget){
let ulMenu = $(this).find('ul');
ulMenu.removeClass('show');
} else {
console.log('fail ');
}
//$(this).find('ul').slideUp();
});
});
Codepen Example Works
You can add a stropPropagation in your click event.
$("#nav1 li").click(
function(e){
e.stopPropagation();
});
maybe the event is getting lost in the process, try to verify it, and if so set the actual element.
see this: https://api.jquery.com/event.relatedTarget/

How to display dropdown menu slider effect from bottom to top after hover?

I have display drop down menu slider effect from bottom to top after hover with linearly and all drop down text should be display left align.
I tried some code but when i hovered first menu my second menu displaying on right side.would you help me in this?
HTML
<div class="right-menu-bar">
<ul class="main-menu">
<li>Menu
<ul>
<li>menu1 details</li>
<li>menu1 details</li>
<li>menu1 details</li>
</ul>
</li>
<li>Menu
<ul>
<li>menu1 details</li>
<li>menu1 details</li>
<li>menu1 details</li>
</ul>
</li>
</ul>
</div>
CSS
.right-menu-bar ul.main-menu > li
{
float: left;
margin: 15px;
font-size: 16px;
}
li ul
{
list-style: none;
background: #3498db;
z-index: 2;
font-size: 16px;
padding:0 ;
}
li ul li
{
text-transform: capitalize;
}
.main-menu li > ul {
display:none;
}
.main-menu li:hover > ul {
display:block;
}
li ul li a{
text-decoration: none;
color: #fff;
padding: 10px 50px;
display:block;
text-align: left !important;
}
li ul li a:hover{
background-color:#5dade2;
text-decoration: none;
color: #000;
}
I thought your problem is stop the second menu slide to right when hover the 1st menu. so adding the position:absolute property to dropdown menu to avoid the second menu sliding.
Now I am adding sideDown() and slideUp() to show or hide the dropdown on menu hover Try below code.
//Hide and Show The Sub Menus
$(".jquery-test ul li.menu-list").hover(function(){
$(this).find('ul').stop().slideDown();
},function(){
$(this).find('ul').stop(true,true).slideUp();
});
.jquery-test ul.menu li.menu-list{display:inline-block;padding-right:20px;}
.jquery-test ul{list-style:none;padding-left:10px;}
.jquery-test ul.menu li.menu-list ul.submenu {display:none;}
.jquery-test ul.menu li.menu-list ul.submenu{position:absolute;}
.jquery-test ul.menu li.menu-list ul.submenu li{position:relative;left:0px;}
.jquery-test ul li a{text-decoration:none;color:#000;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="jquery-test">
<ul class="menu">
<li class="menu-list">Menu1
<ul class="submenu">
<li>Menu1.0</li>
<li>Menu1.1</li>
<li>Menu1.2</li>
<li>Menu1.3</li>
</ul>
</li>
<li class="menu-list">Menu2
<ul class="submenu">
<li>Menu2.1</li>
<li>Menu2.2</li>
<li>Menu2.3</li>
<li>Menu2.4</li>
</ul>
</li>
<li class="menu-list">Menu3
<ul class="submenu">
<li>Menu3.0</li>
<li>Menu3.1</li>
<li>Menu3.2</li>
<li>Menu3.3</li>
</ul>
</li>
</ul>
You can do this by applying position: absolute; to the menus that appear, like this:
.main-menu li:hover > ul {
display:block;
position: absolute;
}
Working Fiddle

StopPropogation() not working

I am coding a multilevel drop down menu in which when the parent is hovered, the submenu drops down with JQuery fadeIn(). But the effect is getting propagated to the child elements. They are also having fadeIn() when hovered on. The code is
HTML
<nav>
<ul id="headnav">
<li> <a class="sliding-middle-out" href="index.php"> ABOUT </a> </li>
<li> <a class="sliding-middle-out" href="practice.php"> PRACTICE </a> </li>
<li> <a class="sliding-middle-out" href="research.php"> RESEARCH </a>
<ul>
<li> Papers </li>
<li> Articles </li>
<li> PhD Students </li>
<li> Presentations </li>
</ul>
</li>
</ul>
</nav>
JQuery
$(document).ready(function() {
$('nav > ul > li > ul').hide();
$('nav > ul > li').hover(function() {
$(this).find('ul').fadeIn(400);
},function() {
$(this).find('ul').fadeOut(400);
});
});
CSS
nav {
position: absolute;
min-width:30%;
float:right;
right:12%;
top: 16%;
}
nav ul li {
display: inline-block;
min-width: 20px;
text-transform: uppercase;
}
nav ul li a{
float: left;
padding: 0px 10px 0px 10px;
}
nav ul li ul {
display: inline-block;
position: absolute;
width: auto;
margin-left:-35%;
margin-top:7%;
}
nav ul li ul li {
display: inline-block;
min-width:10px;
}
nav ul li ul li a {
color:#7f8c8d;
}
When you hover your mouse over the child elements, they again fadeIn(). I tried e.stopPropagation() and e.preventDefault() but none of them are working.
Please help
Show the submenu on hovering over the outer li, but hide it on leaving the inner ul:
$('nav > ul > li').mouseenter(function(e) {
$(this).find('ul').fadeIn(400);
});
$('nav > ul > li > ul').mouseleave(function() {
$(this).fadeOut(400);
});
http://jsfiddle.net/mava7btt/3/

How to Change CSS style of the same element that is NOT Hovered

HTML
<ul id="menu">
<li>Home</li>
<li>Categories
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</li>
<li>Work</li>
<li>About</li>
<li>Contact</li>
</ul>
CSS
#menu li{
width:80px;
}
#menu li:hover {
width:200px;
}
I want to set the width of OTHER <li>s THAT ARE NOT HOVERED to 60PX while one of them are Hovered, and then set width back to 80PX when all of them are not hovered.. how Would I do that?
Using jQuery
jQuery(function ($) {
$('#menu li').hover(function () {
$(this).width(200).siblings().width(60)
}, function () {
$(this).siblings().addBack().width(80)
})
})
Demo: Fiddle
I want to set the width of OTHER <li>s THAT ARE NOT HOVERED to 60PX while one of them are Hovered, and then set width back to 80PX when all of them are not hovered
With jquery you can do like this:
$('#menu li').hover(function(){
$('#menu li').css('width','60px');
$(this).css('width','80px');
},function(){
$('#menu li').css('width','80px');
});
demo
To select li elements that are not :hovered, consider trying:
#menu li{
width:80px;
color: green;
}
#menu:hover li{
color: yellow;
}
#menu li:hover {
width:200px;
color: red;
}
You can achieve that by simply using :hover on both li and ul.
ul li{
width:80px;
}
ul:hover li{
width: 60px;
}
#menu li:hover {
width:200px;
}

Add 2nd sub nav to accordion style menu

I'm looking to have an additional subnav to this accordion menu. I tried to add a child element to the nav ul li, but that didn't seem to work. Ideally, I would like to be able to list web projects under "web" and print under "print".
FIDDLE: http://jsfiddle.net/schermerb/rGMAu/1/
.header button {
cursor:pointer;
float:right;
padding:5px;
margin:10px 10px;
border:none;
border:1px solid #ececec;
background:#444;
color:#ececec;
}
.nav {
text-align:center;
background:#444;
}
.nav ul li {
text-transform:capitalize;
display:block;
border-bottom:1px solid #ececec;
}
.nav a {
display:block;
padding:10px;
color:#ececec;
}
.nav a:hover {
background:#029b9d;
color:#ececec;
}
<button id="show">Menu <span>+</span> <span style="display:none;">-</span>
</button>
<div class="clear"></div>
</div>
<div class="nav">
<ul>
<li>Home
</li>
<li>About
</li>
<li>Web
</li>
<li>Print
</li>
</ul>
</div>
I have updated your js
$('.nav, .nav li ul').hide();
$('#show').click(function () {
$(".nav").toggle();
$("span").toggle();
});
$('.nav li').click(function(){
$(this).children('ul').toggle();
});
Updated jsFiddle File
Adding a child element was the right path.
http://jsfiddle.net/jonigiuro/rGMAu/2/
<li>Web
<ul class="sub">
<li class="item">item1</li>
<li class="item">item2</li>
</ul>
</li>
You hide the child element by default, and when you hover on the parent, you show the it:
ul li:hover ul
Here's the revelant css for your case:
.nav ul li ul {
color: red;
margin: 0;
padding: 0;
display: none;
}
.nav ul li:hover ul {
display: block;
}
.nav ul li ul li {
padding: 10px 0;
}

Categories

Resources