Dropdown menu continues to stay after browser expanded - javascript
I have a responsive menu and I have some problems with it
if you run this code in your laptop in full screen format then change browser width below the breakpoint at 943px, menu changes to mobile format and in this case if you select for example "about option " it's dropdown appears. Howevere if you resize the screen back to full size without first closing "about" drop down, it did not disappear in full screen, it continues to stay even after the browser is fully expanded. and it looks messed up
any idea? thanks
/*global $ */
$(document).ready(function () {
"use strict";
$('.menu > ul > li:has( > ul)').addClass('');
//Checks if li has sub (ul) and adds class for toggle icon - just an UI
$('.menu > ul > li > ul:not(:has(ul))').addClass('normal-sub');
//Checks if drodown menu's li elements have anothere level (ul), if not the dropdown is shown as regular dropdown, not a mega menu (thanks Luka Kladaric)
$(".menu > ul").before("");
$(".menu > ul > li").hover(function (e) {
if ($(window).width() > 943) {
$(this).children("ul").stop(true, false).fadeToggle(150);
e.preventDefault();
}
});
//If width is more than 943px dropdowns are displayed on hover
$(".menu > ul > li").click(function () {
if ($(window).width() <= 943) {
$(this).children("ul").fadeToggle(150);
}
});
$(".menu-mobile").click(function (e) {
$(".menu > ul").toggleClass('show-on-mobile');
e.preventDefault();
});
});
–––––––––––––––––––––––––––––––––––––––––––––––––– */
body {
font-family: 'Source Sans Pro', sans-serif;
}
* {
box-sizing: border-box;
}
a {
color: #333;
}
.description {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
/* ––––––––––––––––––––––––––––––––––––––––––––––––––
megamenu.js STYLE STARTS HERE
–––––––––––––––––––––––––––––––––––––––––––––––––– */
/* ––––––––––––––––––––––––––––––––––––––––––––––––––
Screen style's
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.menu-container {
width: 80%;
margin: 0 auto;
background: #e9e9e9;
}
.menu-mobile {
display: none;
padding: 20px;
}
.menu-mobile:after {
content: "\f394";
font-family: "Ionicons";
font-size: 2.5rem;
padding: 0;
float: right;
position: relative;
top: 50%;
-webkit-transform: translateY(-25%);
-ms-transform: translateY(-25%);
transform: translateY(-25%);
}
.menu-dropdown-icon:before {
content: "\f489";
font-family: "Ionicons";
display: none;
cursor: pointer;
float: right;
padding: 1.5em 2em;
background: #fff;
color: #333;
}
.menu > ul {
margin: 0 auto;
width: 100%;
list-style: none;
padding: 0;
position: relative;
/* IF .menu position=relative -> ul = container width, ELSE ul = 100% width */
box-sizing: border-box;
}
.menu > ul:before,
.menu > ul:after {
content: "";
display: table;
}
.menu > ul:after {
clear: both;
}
.menu > ul > li {
float: left;
background: #e9e9e9;
padding: 0;
margin: 0;
}
.menu > ul > li a {
text-decoration: none;
padding: 1.5em 3em;
display: block;
}
.menu > ul > li:hover {
background: #f0f0f0;
}
.menu > ul > li > ul {
display: none;
width: 100%;
background: #f0f0f0;
padding: 20px;
position: absolute;
z-index: 99;
left: 0;
margin: 0;
list-style: none;
box-sizing: border-box;
}
.menu > ul > li > ul:before,
.menu > ul > li > ul:after {
content: "";
display: table;
}
.menu > ul > li > ul:after {
clear: both;
}
.menu > ul > li > ul > li {
margin: 0;
padding-bottom: 0;
list-style: none;
width: 25%;
background: none;
float: left;
}
.menu > ul > li > ul > li a {
color: #777;
padding: .2em 0;
width: 95%;
display: block;
border-bottom: 1px solid #ccc;
}
.menu > ul > li > ul > li > ul {
display: block;
padding: 0;
margin: 10px 0 0;
list-style: none;
box-sizing: border-box;
}
.menu > ul > li > ul > li > ul:before,
.menu > ul > li > ul > li > ul:after {
content: "";
display: table;
}
.menu > ul > li > ul > li > ul:after {
clear: both;
}
.menu > ul > li > ul > li > ul > li {
float: left;
width: 100%;
padding: 10px 0;
margin: 0;
font-size: .8em;
}
.menu > ul > li > ul > li > ul > li a {
border: 0;
}
.menu > ul > li > ul.normal-sub {
width: 300px;
left: auto;
padding: 10px 20px;
}
.menu > ul > li > ul.normal-sub > li {
width: 100%;
}
.menu > ul > li > ul.normal-sub > li a {
border: 0;
padding: 1em 0;
}
/* ––––––––––––––––––––––––––––––––––––––––––––––––––
Mobile style's
–––––––––––––––––––––––––––––––––––––––––––––––––– */
#media only screen and (max-width: 959px) {
.menu-container {
width: 100%;
}
.menu-mobile {
display: block;
}
.menu-dropdown-icon:before {
display: block;
}
.menu > ul {
display: none;
}
.menu > ul > li {
width: 100%;
float: none;
display: block;
}
.menu > ul > li a {
padding: 1.5em;
width: 100%;
display: block;
}
.menu > ul > li > ul {
position: relative;
}
.menu > ul > li > ul.normal-sub {
width: 100%;
}
.menu > ul > li > ul > li {
float: none;
width: 100%;
margin-top: 20px;
}
.menu > ul > li > ul > li:first-child {
margin: 0;
}
.menu > ul > li > ul > li > ul {
position: relative;
}
.menu > ul > li > ul > li > ul > li {
float: none;
}
.menu .show-on-mobile {
display: block;
}
}
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>megamenu.js | Last responsive megamenu you'll ever need</title>
<meta name="description" content="">
<meta name="keywords" content="" />
<meta name="author" content="Mario Loncarek">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.min.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/ionicons.min.css">
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:300' rel='stylesheet' type='text/css'>
<!-- JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<script>
window.Modernizr || document.write('<script src="js/vendor/modernizr-2.8.3.min.js"><\/script>')
</script>
</head>
<body>
<div class="menu-container">
<div class="menu">
<ul>
<li>Home</li>
<li>About
<ul>
<li>School
<ul>
<li>Lidership</li>
<li>History</li>
<li>Locations</li>
<li>Careers</li>
</ul>
</li>
<li>Study
<ul>
<li>Undergraduate</li>
<li>Masters</li>
<li>International</li>
<li>Online</li>
</ul>
</li>
<li>Research
<ul>
<li>Undergraduate research</li>
<li>Masters research</li>
<li>Funding</li>
</ul>
</li>
<li>Something
<ul>
<li>Sub something</li>
<li>Sub something</li>
<li>Sub something</li>
<li>Sub something</li>
</ul>
</li>
</ul>
</li>
<li>News
<ul>
<li>Today</li>
<li>Calendar</li>
<li>Sport</li>
</ul>
</li>
<li>Contact
<ul>
<li>School
<ul>
<li>Lidership</li>
<li>History</li>
<li>Locations</li>
<li>Careers</li>
</ul>
</li>
<li>Study
<ul>
<li>Undergraduate</li>
<li>Masters</li>
<li>International</li>
<li>Online</li>
</ul>
</li>
<li>Study
<ul>
<li>Undergraduate</li>
<li>Masters</li>
<li>International</li>
<li>Online</li>
</ul>
</li>
<li>Empty sub</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="description">
<h3>megamenu.js - Last responsive megamenu you'll ever need</h3>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/vendor/jquery-1.12.0.min.js"><\/script>')
</script>
<script src="js/megamenu.js"></script>
</body>
</html>
If I understand what your problem is correctly, one way of doing what you want is by refreshing the webpage on resize.
Here is some JavaScript to do it:
window.addEventListener('resize', function(event) {
clearTimeout(resizeTimeout);
var resizeTimeout = setTimeout(function(){
window.location.reload();
}, 300);
});
UPDATE:
Since it's just a menu, it would not be ideal to refresh the whole page so another way is to reduce its z-index, read more about the z-index: http://www.w3schools.com/cssref/pr_pos_z-index.asp
Example:
Javascript:
var currentWidth ;
setInterval(function(){
currentWidth = window.innerWidth;
if(currentWidth < 983) { //983 or whatever threshold you want
document.getElementsByClassName(".menu-container").style.zIndex = -999; //set the value to -999 just to be sure :)
}
else{
document.getElementsByClassName(".menu-container").style.zIndex = 999;
}
}, 300);
The problem is that you can "open" multiple sub-menus in mobile mode via this code:
$(".menu > ul > li").click(function () {
if ($(window).width() <= 943) {
$(this).children("ul").fadeToggle(150);
}
});
What you could do is add code that listens on the windows resize event and then fades the open menus. I did this with the following code. It remembers which sub-menu was opened and then on resize closes them:
var openSubMenu = undefined; // You want to store the open sub-menu here
$('.menu > ul > li:has( > ul)').addClass('menu-dropdown-icon');
//Checks if li has sub (ul) and adds class for toggle icon - just an UI
$('.menu > ul > li > ul:not(:has(ul))').addClass('normal-sub');
//Checks if drodown menu's li elements have anothere level (ul), if not the dropdown is shown as regular dropdown, not a mega menu (thanks Luka Kladaric)
$(".menu > ul").before("Navigation");
//Adds menu-mobile class (for mobile toggle menu) before the normal menu
//Mobile menu is hidden if width is more then 959px, but normal menu is displayed
//Normal menu is hidden if width is below 959px, and jquery adds mobile menu
//Done this way so it can be used with wordpress without any trouble
//If width is more than 943px dropdowns are displayed on hover
$(".menu > ul > li").hover(function (e) {
if ($(window).width() > 943) {
$(this).children("ul").stop(true, false).fadeToggle(150);
e.preventDefault();
}
});
//If width is less or equal to 943px dropdowns are displayed on click (thanks Aman Jain from stackoverflow)
$(".menu > ul > li").click(function () {
if ($(window).width() <= 943) {
var thisItem = $(this).children("ul");
if (openSubMenu && openSubMenu.get(0) != thisItem.get(0)) openSubMenu.fadeOut(0);
openSubMenu = thisItem;
openSubMenu.fadeToggle(150);
//$(this).children("ul").fadeToggle(150);
}
});
//When clicked on mobile-menu, normal menu is shown as a list, classic rwd menu story (thanks mwl from stackoverflow)
$(".menu-mobile").click(function (e) {
$(".menu > ul").toggleClass('show-on-mobile');
e.preventDefault();
});
// When the window resizes clear any open windows
$(window).resize(() => {
if (openSubMenu && openSubMenu.css('display') === 'block') {
openSubMenu.fadeOut(0);
openSubMenu = undefined;
}
})
};
Related
Mobile Sub Navigation not expanding out half of the time
I have been following this and I have very minimal knowledge of JavaScript or of jQuery as of yet. I have run into a problem when developing a website with the use of the above tutorial to make a responsive mob navigation. The Problem: Depending on what size the browser was when launching my html document the sub navigation toggle doesn't (It goes straight to the link instead of opening the sub navigation menu) work if the browser was launched in the range of around 600px's, but works when launched at a smaller screen sized or shrunked down (sometimes). I have been trying to figure out how to fix this problem My code (Tried keeping it minamil, sorry): $(document).ready(function() { //Creating the show/hide function with jQuery Toggle $("#navToggle a").on ('click', function(event){ event.preventDefault(); $("header > nav").slideToggle("medium"); $("#logo").toggleClass("menuUp menuDown"); }); //Tidying up the Navigation Menu $(window).resize(function() { if($( window ).width() >= "600") { $("header > nav").css("display", "block"); $("header > nav > ul > li > a").siblings().removeAttr("style"); if($("#logo").attr('class') == "menuDown") { $("#logo").toggleClass("menuUp menuDown"); } } else { $("header > nav").css("display", "none"); //document.getElementById("categories").href = "categories/index.html"; } }); //Creating the Drop Down Menu for Mobile Devices $("header > nav > ul > li > a").click(function(e) { if($( window ).width() <= "600") { if($(this).siblings().size() > 0 ) { event.preventDefault(); $(this).siblings().slideToggle("fast") $(this).children(".toggle").html($(this).children(".toggle").html() == 'close' ? 'expand' : 'close'); } } }); }); .clearfix:before, .clearfix:after { content: " "; display: table; } .clearfix:after { clear: both; visibility: hidden; } .clearfix { *zoom: 1; } /* Navigation */ /* Mobile */ header > div#logo { line-height: 70px; position: relative; } header > .menuDown { box-shadow: 0 3px 5px rgba(0,0,0,.15); } header > .menuUp { box-shadow: none; } header > div#logo > h1 { font-size: 48px; font-size: 3rem; /* 48px fallback */ font-weight: bold; text-rendering: optimizeLegibility; } header > div#logo > div#navToggle { background-color: rgba(0,0,0,.15); position: absolute; right: 0; top: 0; transition: 300ms all ease; } header > div#logo > div#navToggle:hover { background-color: rgba(0,0,0,.1); } header > div#logo > div#navToggle > a { color: rgba(255,255,255,.85); display: block; font-size: 0.85em; font-weight: 600; padding: 0 2.5rem; text-decoration: none; transition: 300ms all ease; } header > div#logo > div#navToggle:hover > a { color: rgba(255,255,255,1); } header > nav { background-color: rgba(0,0,0,0.20); display: none; flex: 1; transform: 300ms all ease; } header nav > ul { list-style-type: none; } header nav > ul > li { border-bottom: 1px dotted rgba(0,0,0,.1); position: relative; } header nav > ul > li:last-of-type { border-bottom: none; } header nav > ul > li > a { display: block; color: rgba(0,0,0,.65); font-weight: 700; padding: 1.5rem 0; text-decoration: none; transition: 250ms all ease; } header nav > ul > li > a:visited { color: rgba(0,0,0,.65); } header nav > ul > li > a span.toggle { background-color: rgba(0,0,0,.05); border-radius: 3rem; color: rgba(0,0,0,.25); font-size: 0.75em; font-weight: 500; padding: 2px 8px; text-transform: lowercase; } header nav > ul > li > a span.caret { display: none; } header > nav > ul > li:hover > a { color: rgb(140, 193, 193); } header > nav > ul > li > nav { background-color: rgb(51,51,51); border-radius: 1.5em; box-shadow: 0 2px 8px rgba(0,0,0,.6); display: none; overflow: hidden; position: absolute; right: 5%; width: 90%; z-index: 100; text-align: left; } header > nav > ul > li > nav > ul > li > a { color: rgba(255,255,255,.85); transition: 300ms all ease; font-size: 14px; /* Modify till find correct size */ } header > nav > ul > li > nav > ul > li > a:visited { color: rgba(255,255,255,.85); } header > nav > ul > li > nav > ul > li:hover > a { background-color: rgba(0,0,0,.6); color: rgba(255,255,255,1); } #media only screen and (min-width: 48rem) { /* For tablets #768px: */ header > div#logo > div#navToggle { display: none; } header { background-color: white; flex-direction: row; line-height: 90px; padding: 0 3rem; position: fixed; width: 100%; display:inline; } header > div#logo { background-color: transparent; line-height: 90px; } header > div#logo > h1 { color: rgb(140, 193, 193); } header > nav { background-color: transparent; display: block; } header > nav > ul { display: flex; flex-flow: row wrap; justify-content:space-around; } header nav > ul > li { border-bottom: none; } header nav > ul > li > a { padding: 0 1.25rem; } header nav > ul > li > a span.toggle { display: none; } header nav > ul > li > a span.caret { border-bottom: 4px solid transparent; border-top: 4px solid rgba(0,0,0,.65); border-right: 4px solid transparent; border-left: 4px solid transparent; border-radius: 1px; content: ""; display: inline-block; height: 0; margin: 0 0 0 .25rem; transition: 250ms all ease; width: 0; vertical-align: middle; } header nav > ul > li:hover > a span.caret { border-top-color: rgb(140, 193, 193); transform: rotate(270deg); } header > nav > ul > li:hover > nav { background-color: rgb(51,51,51); border-radius: .25em; box-shadow: 0 2px 8px rgba(0,0,0,.6); display: block; line-height: 3em; right: -50%; width: 12.25rem; /* 196px */ } } #media screen and (min-width: 95.625rem) { header { display:flex } } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <html> <body> <head> <meta charset="utf-8"> <meta name="description" content="Daily technology walkthroughs for everyones needs "> <meta name="HandheldFriendly" content="True"> <meta name="MobileOptimized" content="320"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>The Daily Tech Walkthroughs</title> </head> <header class="clearfix"> <div id="logo" class="menuUp"> <h1> The Daily Tech <br> Walkthroughs </h1> <div id="navToggle">Menu</div> </div> <nav class="clearfix primary-nav"> <ul> <li>Home</li> <li>Walkthroughs</li> <li id="mobile-version-click"> Categories <span class="toggle">Expand</span><span class="caret"></span> <nav> <ul> <li>All Categories</li> <li>Computers</li> <li>Consoles</li> <li>Phones and Tablets</li> <li>Gadgets</li> <li>Other Technology</li> </ul> </nav> </li> <li>Create a Walkthrough</li> <li>Help</li> <li>About</li> <li id="mobile-version-click"> User <span class="toggle">Expand</span><span class="caret"></span> <nav> <ul> <li>Profile</li> <li>Settings</li> <li>Logout</li> </ul> </nav> </li> <li><div class="search"><input type="search" placeholder="search..." /></div></li> </ul> </nav> </header> </body> </html>
The Problem was a stupid oversight on my part, I had forgot to change my screen size values in my javascript, after I had change my breakpoints in my css. The valuse had to change from 600px to 767px for the javascript to work. Changes to the javascript below. $(document).ready(function() { //Creating the show/hide function with jQuery Toggle $("#navToggle a").on ('click', function(event){ event.preventDefault(); $("header > nav").slideToggle("medium"); $("#logo").toggleClass("menuUp menuDown"); }); //Tidying up the Navigation Menu $(window).resize(function() { if($( window ).width() >= "767") { $("header > nav").css("display", "block"); $("header > nav > ul > li > a").siblings().removeAttr("style"); if($("#logo").attr('class') == "menuDown") { $("#logo").toggleClass("menuUp menuDown"); } } else { $("header > nav").css("display", "none"); //document.getElementById("categories").href = "categories/index.html"; } }); //Creating the Drop Down Menu for Mobile Devices $("header > nav > ul > li > a").click(function(e) { if($( window ).width() <= "767") { if($(this).siblings().size() > 0 ) { event.preventDefault(); $(this).siblings().slideToggle("fast") $(this).children(".toggle").html($(this).children(".toggle").html() == 'close' ? 'expand' : 'close'); } } }); });
Why are the anchors in my submenu returning false?
I am writing a jquery dropdown script for my navigation submenus. I have return false on the top level anchors but the problem is that this is also applying to the anchors in the submenus. My script also adds chevrons to the top level links that have submenus but those are also being added to the submenu links. What am I doing wrong? Here is a jsFiddle. Thanks for your time. <div class="nav-outter"> <nav> <ul> <li>Home</li> <li class="has-submenu">Services <ul> <li>Web Development</li> <li>Photography</li> <li>Multimedia</li> </ul> </li> </ul> </nav> </div> $(document).ready(function() { $('nav > ul > li.has-submenu').each(function() { $(this).find('a:first-child').each(function() { $(this).append('<i class="fa fa-chevron-down"></i>'); $(this).on('click', function(e) { e.preventDefault(); $(this).parent().find('ul').each(function() { if ($(this).hasClass('active')) { $(this).removeClass('active') .slideUp(300); } else { $(this).addClass('active') .slideDown(300); } }); }); }); }); }); .nav-outter { position: relative; z-index: 1; } nav > ul { list-style: none; } nav > ul > li { display: inline-block; } nav > ul > li > a { padding: 3px 15px; font-size: 1.2em; color: #2c3e50; text-decoration: none; } nav > ul > li > ul { display: none; position: absolute; z-index: 5; list-style: none; border: 1px solid #FC4349; border-bottom: 0px; margin-left: 0px; padding-left: 0px; margin-top: 3%; } nav > ul > li > ul > li { border-bottom: 1px solid #FC4349; } nav > ul > li > ul > li > a { display: block; padding: 15px 25px 15px 10px; text-align: left; background: #fff; color: #FC4349; text-decoration: none; }
The find('a:first-child') is going to include every first child which is all of the links since each one is a first-child A simpler approach would be just target the children of has-submenu and remove one each $('nav > ul > li.has-submenu').children('a').each(function() { $(this).append('<i class="fa fa-chevron-down"></i>'); $(this).on('click', function(e) { ..... Or using your code if you had used find('a:first') it would have worked since you would be targeting only the first <a> in each of those class
styling third level of menu not working
In my attempt to create mega menu, im stuck with styling third level of submenu. First submenu (li ul) is not displayed (display: none). Then i have jquery script that shows that submenu on hover ( li ul - first level ). If window is less then 768px then the click function is activated (for touch screens). My problem is when i want to style the third level sub menu ( submenu of submenu - li - ul - li - ul ) no style is applied - i want it to be shown always, but is hidden, display: none is applied on that UL but i styled it as display: block. So its only shown when i hover its LI element (li ul li hover). So basically what im trying to do is that first submenu (li - ul) is activated on hover (or click for phones) but that second submenu (submenu of submenu) is allways visible. When i try to style it i access it like this: li ul li ul, and that is not working. How should i access it? Also when i try to hover that third level submenu, menu closes and i did not specify it like that in jquery. HTML <div class="menu-container"> <ul class="menu"> <li>Home <ul> <li>Ovo je nesto <ul> <li>aaa</li> </ul> </li> <li>Ovo je nesto</li> <li>Ovo je nesto</li> <li>Ovo je nesto</li> </ul> </li> <li>Who are we? <ul> <li>This is mega menu</li> </ul> </li> <li>Services</li> <li>Contact</li> </ul> </div> CSS .menu-container { width: 80%; margin: 0 auto; background: #333; } .menu { margin: 0 auto; list-style: none; padding: 0; position: relative; } .menu:before, .menu:after { content: ""; display: table; } .menu:after { clear: both; } .menu li { float: left; background: #e9e9e9; padding: 0; margin: 0; } .menu li a { text-decoration: none; padding: 1.5em 3em; display: inline-block; outline: 0 none; } .menu li ul { display: none; width: 100%; background: #333; padding: 20px; position: absolute; z-index: 99; left: 0; color: #fff; margin: 0; } .menu li ul li { margin: 0; padding: 0; list-style: none; width: 25%; background: none; float: left; } .menu li ul li a { color: #fff; padding: .2em 0; } .menu li ul li ul { display: block; } .menu li ul li ul li { display: block; } /* –––––––––––––––––––––––––––––––––––––––––––––––––– 960px –––––––––––––––––––––––––––––––––––––––––––––––––– */ /* –––––––––––––––––––––––––––––––––––––––––––––––––– TABLETS –––––––––––––––––––––––––––––––––––––––––––––––––– */ /* –––––––––––––––––––––––––––––––––––––––––––––––––– MOBILE 100% –––––––––––––––––––––––––––––––––––––––––––––––––– */ #media only screen and (max-width: 767px) { .menu > li { float: none; width: 100%; } .menu > li > ul { position: relative; } .menu > li > ul li { float: none; width: 100%; } } Jquery $(document).ready(function () { $(".menu li").hover(function () { if ($(window).width() > 767) { $('.menu ul li ul').not($(this).children("ul").fadeToggle(200)).hide(); } }); $(".menu li").click(function () { if ($(window).width() <= 767) { $('.menu ul li ul').not($(this).children("ul").fadeToggle(200)).hide(); } }); }); Demo: http://codepen.io/riogrande/pen/ZbaeKa
The CSS selector .menu li ul li ul li will select all list items in the 3rd level submenu or lower. As sodawillow mentioned, you can either use classes or the direct descendent selector > to fine tune styles for specific submenu levels. The following snippets will fix the submenu hovering effect to be more intuitive - by having all menus hidden until its parent is hovered over. JavaScript - replace the entire fade/hide statement with this: $(this).children("ul").fadeToggle(200); CSS: .menu li ul li ul { display: none; } If you want the second submenu to be visible when the first submenu is visible, the jQuery selector should be $(".menu > li") instead to select just the first submenu, and the CSS can be left as is.
These selectors may target the same li elements, the first one is very broad and cancels the rules for the following ones : .menu li ul { display: none; width: 100%; background: #333; padding: 20px; position: absolute; z-index: 99; left: 0; color: #fff; margin: 0; } .menu li ul li { margin: 0; padding: 0; list-style: none; width: 25%; background: none; float: left; } .menu li ul li ul { display: block; } .menu li ul li ul li { display: block; } You may use the > selector to target only direct children, but I'd strongly advise using classes instead, to help separating styles between levels : <div class="menu-container"> <ul class="menu-level1"> <li>Home <ul class="menu-level2"> <li>Ovo je nesto <ul class="menu-level3"> <li>aaa</li> </ul> </li> <li>Ovo je nesto</li> <li>Ovo je nesto</li> <li>Ovo je nesto</li> </ul> </li> <li>Who are we? <ul class="menu-level2"> <li>This is mega menu</li> </ul> </li> <li>Services</li> <li>Contact</li> </ul> </div>
How to make twitter bootstrap dropdown hide when using the JS without CSS?
I don't want to include bootstrap in my project, but I want to use the dropdown plugin separately. The reason I chose Bootstrap's one because it's a robust and relatively non-complicated one (I just need the basic functionality – to work flawlessly, not any extra features) I tried to make the dropdown css as close to bootstrap's css as possible, but the menu refuses to hide when I click outside the dropdown. HTML: <div id="top_links"> <ul> <li class="dropdown"> Menu <ul class="dropdown-menu"> <li> Submenu 1 </li> <li> Submenu 1 </li> <li> Submenu 1 </li> </ul> </li> </ul> </div> JS (tried both including full bootstrap.js and just bootstrap-dropdown.js plugin): $('#top_links').find("li.dropdown > a").dropdown() CSS: #top_links > ul { list-style-type: none; } #top_links > ul > li { position: relative; display: inline-block; vertical-align: baseline; zoom: 1; *display: inline; *vertical-align: auto; margin-left: 28px; } #top_links > ul > li:first-child { margin-left: 0; } #top_links > ul > li > a { display: block; text-decoration: none; position: relative; padding-top: 28px; } #top_links > ul > li > a:before { content:""; width: 30px; height: 20px; position: absolute; top: 0; left: 50%; margin-left: -15px; } #top_links > ul > li.dropdown > a { margin-right: 13px; } #top_links > ul > li.dropdown:after { content:""; position: absolute; right: 0; bottom: 6px; width: 8px; height: 6px; } #top_links > ul > li > ul { display: none; list-style-type: none; position: absolute; z-index: 10; width: auto; border: 1px solid #edeae6; background-color: #f6f3ef; padding: 5px; margin: 0 -6px 0px -6px; } #top_links > ul > li > ul li { padding: 5px 0; } #top_links > ul > li > ul li a { display: block; } #top_links > ul > li > ul li > .icon { top: 6px !important; } #top_links > ul > li.open > ul { display: block; } On JSFiddle: Live DEMO
This seems to work when I don't use the manual trigger, so I removed this line: $('#top_links').find("li.dropdown > a").dropdown() And added data-toggle attribute to the links: Menu Works now: DEMO However, do you think this is a bug in Bootstrap? Is it intended to work as I tried it?
Try this <script> $(document).ready(function () { $(".dropdown").on('click', function () { $(".dropdown-menu").toggle("slow"); }); }); $(".dropdown").on("click", function (event) { event.stopPropagation(); }); $(document).on("click", function () { $(".dropdown-menu").toggle("slow"); }); </script> Demo http://jsfiddle.net/hg2T6/2/
I would like a menu submenu using javascript or any other way possible
I've searched and tried multiple way to accomplish this to no avail... i have provided my current code below....please feel free to critique and provide with any help necessary... <script src="jquery.js"></script> <div id="navigation"> <p>Leave A Note</p> <ul id="menu"> <li>Artist<ul> <li>Sketchbook</li><li>Music</li><li>Artwork</li><li> Media</li><li>Words</li></ul> </li> <li>UI/UX Developer<ul><li>Portfolio</li><li>Resume</ul></li></div> <!--above is the html container--> <!--Now add javascript to control the hiding and such--> <script> var showMenuText = $('#toggle').text(); var hideMenuText = 'Close'; $('#navigation ul').hide(); $('#navigation ul a.active+ul').show(); hideMenu = function() { $('#navigation ul#menu').hide(); $('#navigation').removeClass('Open'); $('#toggle').text(showMenuText); } $('#toggle').click(function(event){ event.stopPropogation(); event.preventDefault(); $('#navigation ul#menu').toggle(); $('#navigation').toggleClass('open'); var toggleText = $('#toggle').text(); (toggleText == showMenuText) ? $(this).text(hideMenuText) : $(this).text(showMenuText);}); $('ul#menu > li > a').click(function(event){ $this = $(this); if ($this.hasClass('page') ) parent.location = $this.attr('href'); if ($this.hasClass('home') ) { parent.location = '/'; } event.preventDefault(); event.stopPropagation(); if( $this.hasClass('active') ) var justclosed = true; $('a.active').removeClass('active').next('ul').hide(); if(!justclosed) $this.addClass('active').next('ul').show(); }); </script> here the javascript is not doing as what i expect it to..as the unordered lists are still showing as a list and are not hidden....any advice would be greatly appreciated!..
You're missing a closing li at this line: <li>UI/UX Developer<ul><li>Portfolio</li><li>Resume</ul></li></div> This should be <li>UI/UX Developer<ul><li>Portfolio</li><li>Resume</li></ul></li></div> Maybe this is causing the javascript issue.
Drop Down menus can be done by Pure CSS with relative and absolute elements. Consider the following HTML: <ul> <li>Level 1</li> <li> Level 2 <ul> <li>Level 2-1</li> <li>Level 2-2</li> <li>Level 2-3</li> <li>Level 2-4</li> <li>Level 2-5</li> </ul> </li> <li>Level 3</li> <li>Level 4</li> <li>Level 5</li> </ul> Horizontal Working jsFiddle Demo ul { list-style-type: none; margin: 0; padding: 0; } ul ul { position: absolute; top: 20px; left: -1px; display: none; } ul ul li + li { margin-left: 0; margin-top: -1px; } ul li { position: relative; list-style-type: none; margin: 0; padding: 0; color: blue; border: 1px solid blue; width: 150px; float: left; text-align: center; cursor: pointer; height: 20px; } ul li + li { margin-left: -1px; } ul li:hover { background: #b0e0e6; } ul li:hover ul { display: block; } Vertical Working jsFiddle Demo ul { list-style-type: none; margin: 0; padding: 0; } ul ul { position: absolute; top: -1px; left: 150px; display: none; } ul li { position: relative; list-style-type: none; margin: 0; padding: 0; color: blue; border: 1px solid #4169e1; width: 150px; text-align: center; cursor: pointer; height: 20px; } ul li + li { margin-top: -1px; } ul li:hover { background: #b0e0e6; } ul li:hover ul { display: block; }