I'm trying to build a menu with a submenu. I used forEach to loop over the menu items and inside of it I used a for loop to show the submenu for that specific menu. However when I click on the parent menu all the submenus appear (Example 1 below)
I'm fairly new to Javascript. Is there a way to fix this? or maybe a better way to do it?.
Thanks!
Example 1
Here is the JS code:
const navMobile = document.querySelector(".mobile-nav");
const menuLink = navMobile.childNodes;
const subMenu = document.querySelectorAll(".mobile-submenu");
menuLink.forEach((link) => {
link.addEventListener("click", () => {
subMenu.forEach((sublink) => {
sublink.classList.toggle("mobile-submenu-visible");
sublink.classList.remove("collapse");
});
});
});
HTML
<ul class="mobile-nav">
<li class="nav-menu-element">
<a href="#" class="nav-link-mobile"> Product
<img
src="./images/icon-arrow-dark.svg"
class="arrow-nav-mobile"
alt=""
/></a>
<ul class="mobile-submenu collapse">
<li>Overview</li>
<li>Pricing</li>
<li>Marketplace</li>
<li>Features</li>
<li>Integrations</li>
</ul>
</li>
<li class="nav-menu-element">
<a href="#" class="nav-link-mobile">Company
<img
src="./images/icon-arrow-dark.svg"
class="arrow-nav-mobile"
alt=""
/></a>
<ul class="mobile-submenu collapse">
<li>About</li>
<li>Team</li>
<li>Blog</li>
<li>Careers</li>
</ul>
</li>
<li class="nav-menu-element">
<a href="#" class="nav-link-mobile">Connect
<img
src="./images/icon-arrow-dark.svg"
class="arrow-nav-mobile"
alt=""
/></a>
<ul class="mobile-submenu collapse">
<li>Contact</li>
<li>Newsletter</li>
<li>LinkedIn</li>
</ul>
</li>
<nav class="nav-btns-mobile">
Login
Sign Up
</nav>
</ul>
<ul class="desktop-nav">
<li class="nav-link">
Product
<img
src="./images/icon-arrow-light.svg"
class="arrow-nav"
alt=""
/>
<ul>
<li>Overview</li>
<li>Pricing</li>
<li>Marketplace</li>
<li>Features</li>
<li>Integrations</li>
</ul>
</li>
<li class="nav-link">
Company
<img
src="./images/icon-arrow-light.svg"
class="arrow-nav"
alt=""
/>
<ul>
<li>About</li>
<li>Team</li>
<li>Blog</li>
<li>Careers</li>
</ul>
</li>
<li class="nav-link">
Connect
<img
src="./images/icon-arrow-light.svg"
class="arrow-nav"
alt=""
/>
<ul>
<li>Contact</li>
<li>Newsletter</li>
<li>LinkedIn</li>
</ul>
</li>
</ul>
CSS:
.mobile-nav {
background-color: white;
position: absolute;
left: 50%;
top: 5rem;
transform: translateX(-50%);
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 2rem;
padding: 2rem;
border-radius: 0.6rem;
box-shadow: 0px 5px 30px 4px rgba(0, 0, 0, 0.13);
visibility: hidden;
}
.mobile-nav-open {
visibility: visible;
}
.nav-link-mobile {
font-family: "Ubuntu", sans-serif;
font-size: 1.4rem;
font-weight: 400;
color: hsl(208, 49%, 24%);
cursor: pointer;
text-decoration: none;
}
.arrow-nav-mobile {
width: 14px;
}
.mobile-submenu {
list-style: none;
font-family: "Ubuntu", sans-serif;
color: hsl(236, 11%, 49%);
background-color: hsl(0, 0%, 93%);
padding: 2rem 7rem;
font-size: 1.2rem;
margin-top: 2rem;
border-radius: 0.6rem;
cursor: pointer;
}
.mobile-submenu li {
padding-bottom: 1rem;
}
.mobile-submenu-visible {
display: block;
}
.collapse {
display: none;
}
Here's what I did, though when I try your CSS I can't seem to find the link to toggle the sub menu. Basically I add some id to your menuLink and only change the class of sub menu based on the id of the link you clicked.
Javascript
const navMobile = document.querySelector(".mobile-nav");
const menuLink = navMobile.childNodes;
const subMenu = document.querySelectorAll(".mobile-submenu");
menuLink.forEach((link) => {
link.addEventListener("click", () => {
subMenu.forEach((sublink) => {
const dictionary = {
'product-link': 'product-submenu',
'company-link': 'company-submenu',
'connect-link': 'connect-submenu'
}
if (dictionary[link.id] === sublink.id) {
sublink.classList.toggle("mobile-submenu-visible");
sublink.classList.remove("collapse");
// sublink.classList.toggle("collapse"); // uncomment this and delete the remove("collapse") and else block if you want it to be toggle able
} else {
sublink.classList.toggle("mobile-submenu");
sublink.classList.add("collapse");
}
});
});
});
HTML
<ul class="mobile-nav">
<li class="nav-menu-element" id="product-link">
<a href="#" class="nav-link-mobile"> Product
<img src="./images/icon-arrow-dark.svg" class="arrow-nav-mobile" alt="" /></a>
<ul class="mobile-submenu collapse" id="product-submenu">
<li>Overview</li>
<li>Pricing</li>
<li>Marketplace</li>
<li>Features</li>
<li>Integrations</li>
</ul>
</li>
<li class="nav-menu-element" id="company-link">
<a href="#" class="nav-link-mobile">Company
<img src="./images/icon-arrow-dark.svg" class="arrow-nav-mobile" alt="" /></a>
<ul class="mobile-submenu collapse" id="company-submenu">
<li>About</li>
<li>Team</li>
<li>Blog</li>
<li>Careers</li>
</ul>
</li>
<li class="nav-menu-element" id="connect-link">
<a href="#" class="nav-link-mobile">Connect
<img src="./images/icon-arrow-dark.svg" class="arrow-nav-mobile" alt="" /></a>
<ul class="mobile-submenu collapse" id="connect-submenu">
<li>Contact</li>
<li>Newsletter</li>
<li>LinkedIn</li>
</ul>
</li>
<nav class="nav-btns-mobile">
Login
Sign Up
</nav>
</ul>
<ul class="desktop-nav">
<li class="nav-link">
Product
<img src="./images/icon-arrow-light.svg" class="arrow-nav" alt="" />
<ul>
<li>Overview</li>
<li>Pricing</li>
<li>Marketplace</li>
<li>Features</li>
<li>Integrations</li>
</ul>
</li>
<li class="nav-link">
Company
<img src="./images/icon-arrow-light.svg" class="arrow-nav" alt="" />
<ul>
<li>About</li>
<li>Team</li>
<li>Blog</li>
<li>Careers</li>
</ul>
</li>
<li class="nav-link">
Connect
<img src="./images/icon-arrow-light.svg" class="arrow-nav" alt="" />
<ul>
<li>Contact</li>
<li>Newsletter</li>
<li>LinkedIn</li>
</ul>
</li>
</ul>
Related
I'm in trouble with some li in a menu. I made a sandbox with what i have made, i'm struggling at making the div in blue fill the height correctly or with auto height. The menu on the left (red one) is okay. That should be like in this menu (https://www.superc.ca/ in "EPICERIE EN LIGNE") : https://i.stack.imgur.com/aKo36.png
My CSS :
#header .navbar-responsive-collapse-mainMenu {
border-top: gray;
padding: 0;
border-top-width: 2px;
}
#header .navbar-responsive-collapse-mainMenu span.title {
color: #242932;
font-size: 12px;
letter-spacing: 0;
line-height: 14px;
text-align: center;
}
#header .navbar-responsive-collapse-mainMenu .nav-menu-header {
margin-left: 160px;
}
#header .navbar-responsive-collapse-mainMenu ul li a {
font-family: rubikmedium;
color: #242932;
font-size: 14px;
font-weight: 500;
letter-spacing: 0;
line-height: 17px;
}
#header
div.navbar-responsive-collapse-mainMenu
ul.nav-menu-header
> :first-child.open
> a {
color: #e31937;
}
#header
div.navbar-responsive-collapse-mainMenu
ul.nav-menu-header
> :first-child
> a {
padding-left: 0;
}
#header .open > .dropdown-menu {
display: flex;
flex-direction: column;
left: -161px;
height: 550px;
background-color : black;
width: 1440px;
}
#header .ul-level-1 .li-level-1 {
height: 40px;
width: 264px;
background-color: #FF7276;
margin-left: 160px;
}
#header .ul-level-1 .li-level-1 a {
color: #242932;
font-family: latoregular;
font-size: 14px;
letter-spacing: 0;
line-height: 22px;
}
#header .ul-level-1 .li-level-1 .ul-level-2 {
margin-left: 275px;
width: 1005px;
display: flex;
flex-wrap: wrap;
}
#header .ul-level-1 .li-level-1 .ul-level-2 .li-level-2 {
width: 265px;
margin-bottom: 8px;
margin-left : 20px;
background-color : #add8e6;
display: inline-block;
position: relative;
}
This is my html :
<header id="header">
<nav class="navbar ng-isolate-scope" data-rbs-website-menu="" data-block-id="mainMenu" style="margin-bottom: 0;">
<div class="collapse navbar-collapse navbar-responsive-collapse-mainMenu">
<ul class="nav navbar-nav nav-menu nav-menu-header">
<li class="dropdown open">
<a data-toggle="dropdown" class="dropdown-toggle" target="_self" aria-expanded="true">
Les produits <b class="caret"></b>
</a>
<ul class="dropdown-menu ul-level-1">
<li class=" li-level-1">
<a target="_self">offre du moment</a>
<ul class="dropdown-sub-menu list-unstyled ul-level-2">
<li class=" li-level-2">
<a target="_self">First Category</a>
<ul class="dropdown-sub-menu list-unstyled ul-level-3">
<li class=" li-level-3">
<a target="_self">first sub-element</a>
</li>
<li class=" li-level-3">
<a target="_self">second sub-element</a>
</li>
</ul>
</li>
<li class=" li-level-2">
<a target="_self">Second Category</a>
<ul class="dropdown-sub-menu list-unstyled ul-level-3">
<li class=" li-level-3">
<a target="_self">Blanc, typex et correcteurs</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos à plumes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
</ul>
</li>
<li class=" li-level-2">
<a target="_self">Third Category</a>
<ul class="dropdown-sub-menu list-unstyled ul-level-3">
<li class=" li-level-3">
<a target="_self">Ciseaux, équerres, compas</a>
</li>
</ul>
</li>
<li class=" li-level-2">
<a target="_self">Fourth Category
</li>
<li class=" li-level-2">
<a target="_self">Fifth Category</a>
<ul class="dropdown-sub-menu list-unstyled ul-level-3">
<li class=" li-level-3">
<a target="_self">Blanc, typex et correcteurs</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos à plumes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
</ul>
</li>
<li class=" li-level-2">
<a target="_self">Fifth Category</a>
<ul class="dropdown-sub-menu list-unstyled ul-level-3">
<li class=" li-level-3">
<a target="_self">Blanc, typex et correcteurs</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos à plumes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos à plumes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
</ul>
</li>
<li class=" li-level-2">
<a target="_self">Fifth Category</a>
<ul class="dropdown-sub-menu list-unstyled ul-level-3">
<li class=" li-level-3">
<a target="_self">Blanc, typex et correcteurs</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos à plumes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos à plumes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos à plumes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
<li class=" li-level-3">
<a target="_self">stylos billes</a>
</li>
</ul>
</li>
</ul>
</li>
<li class=" li-level-1">
<a target="_self">Les produits les plus vendus</a>
</li>
<li class=" li-level-1">
<a target="_self">Cartouches d’encre</a>
</li>
<li class=" li-level-1">
<a target="_self">Imprimantes</a>
</li>
<li class=" li-level-1">
Papiers
</li>
<li class=" li-level-1">
<a target="_self">Fauteuils & chaises</a>
</li>
<li class=" li-level-1">
<a target="_self">Services généraux</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
</header>
This is my sandbox if you have any idea : https://codepen.io/Kh4yz/pen/XWEqOqN
You can always inspect a webpage and see how the CSS is implemented.
#header .ul-level-1 .li-level-1 .ul-level-2 {
margin-left: 275px;
width: 1005px;
/* Remove flex */
column-count: 3;
}
#header .ul-level-1 .li-level-1 .ul-level-2 .li-level-2 {
width: 265px;
margin-bottom: 8px;
margin-left : 20px;
background-color : #add8e6;
display: inline-block;
position: relative;
float: left; /* This is missing */
}
I have a vertical menu with submenu. I want to close the the previous clocked menu when clicking the new one. I just could open it. but byt this code all of them stay open. how can I do that?
this is the HTML code
<div class="sidebar ">
<div class="menu-layout">
<ul>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa icon-users"></i><span data-i18n="" class="menu-title">User Manangement</span> <span class='fa fa-caret-down right'></span></a>
<ul>
<li class="second-level">* Users List</li>
<li class="second-level"> * Register New User *</li>
</ul>
</li>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa fa-leaf"></i><span data-i18n="" class="menu-title">Categories</span> <span class='fa fa-caret-down right'></span></a>
<ul>
<li class="second-level">* Category List</li>
<li class="second-level">* New category</li>
</ul>
</li>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa fa-product-hunt"></i><span data-i18n="" class="menu-title"> Products</span> <span class='fa fa-caret-down right'></span></a>
<ul>
<li class="second-level">* Products List</li>
<li class="second-level"> * New Product </li>
</ul>
</li>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa fa-product-hunt"></i><span data-i18n="" class="menu-title"> Orders</span> <span class='fa fa-caret-down right'></span></a>
<ul>
<li class="second-level">* Orders List</li>
</ul>
</li>
</ul>
</div>
</div>
This is js:
<script>
$('.sub-menu ul').hide();
$(".sub-menu a").click(function () {
$(this).parent(".sub-menu").children("ul").slideToggle("100");
$(this).find(".right").toggleClass("fa-caret-up fa-caret-down");
});
</script>
and this is CSS:
.menu-layout .first-level {
margin-bottom: 9px;
border-radius: 5%;
padding: 2px 10px 2px 10px;
line-height: 15px;
}
.second-level {
margin-bottom: 9px;
padding: 2px 50px 2px 10px;
line-height: 15px;
}
.menu-layout li a {
color: white !important;
font-size: 13px;
}
.menu-layout li a i {
color: white;
padding-left: 10px
}
.sidebar {
position: fixed;
top: 1px;
width: 250px;
height: calc(100% - 1px);
border-bottom-left-radius: 20px;
transition: all 0.3s ease;
background-color:black;
font-family: IRANSans;
font-weight: 400;
}
Here you go...
Just change this...
$(document).ready(function () {
$(".sub-menu ul").hide();
$(".sub-menu a").click(function () {
$(this).parent(".sub-menu").children("ul").slideToggle("100");
$(this).find(".right").toggleClass("fa-caret-up fa-caret-down");
});
});
...to this.
$(document).ready(function () {
$(".sub-menu ul").hide();
$(".sub-menu a").click(function () {
$(".sub-menu ul").not(this).hide(); // Hide everything, but not "this".
$(this).parent(".sub-menu").children("ul").slideToggle("100");
$(this).find(".right").toggleClass("fa-caret-up fa-caret-down");
});
});
$(document).ready(function() {
$(".sub-menu ul").hide();
$(".sub-menu a").click(function() {
$(".sub-menu ul").not(this).hide(); // Hide everything, but not "this".
$(this).parent(".sub-menu").children("ul").slideToggle("100");
$(this).find(".right").toggleClass("fa-caret-up fa-caret-down");
});
});
.menu-layout .first-level {
margin-bottom: 9px;
border-radius: 5%;
padding: 2px 10px 2px 10px;
line-height: 15px;
}
.second-level {
margin-bottom: 9px;
padding: 2px 50px 2px 10px;
line-height: 15px;
}
.menu-layout li a {
color: white !important;
font-size: 13px;
}
.menu-layout li a i {
color: white;
padding-left: 10px
}
.sidebar {
position: fixed;
top: 1px;
width: 250px;
height: calc(100% - 1px);
border-bottom-left-radius: 20px;
transition: all 0.3s ease;
background-color: black;
font-family: IRANSans;
font-weight: 400;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="sidebar ">
<div class="menu-layout">
<ul>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa icon-users"></i><span data-i18n="" class="menu-title">User Manangement</span> <span class="fa fa-caret-down right"></span></a>
<ul>
<li class="second-level">* Users List</li>
<li class="second-level"> * Register New User *</li>
</ul>
</li>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa fa-leaf"></i><span data-i18n="" class="menu-title">Categories</span> <span class="fa fa-caret-down right"></span></a>
<ul>
<li class="second-level">* Category List</li>
<li class="second-level">* New category</li>
</ul>
</li>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa fa-product-hunt"></i><span data-i18n="" class="menu-title"> Products</span> <span class="fa fa-caret-down right"></span></a>
<ul>
<li class="second-level">* Products List</li>
<li class="second-level"> * New Product </li>
</ul>
</li>
<li class="sub-menu nav-item first-level">
<a class="nav-link text-truncate" href="#"><i class="fa fa-product-hunt"></i><span data-i18n="" class="menu-title"> Orders</span> <span class="fa fa-caret-down right"></span></a>
<ul>
<li class="second-level">* Orders List</li>
</ul>
</li>
</ul>
</div>
</div>
</body>
</html>
AM trying to have to actions on a nav menu (open and close)
this is my code :
Here, i can open the item and hide it when i click outside BUT I need also to close the item when i click on the link .menu-item-has-children > a
var click_item = function() {
$('.menu-item-has-children > a').on('click', function() {
var EltToToggle = $(this).next('.sub-menu');
if ($(this).attr('href') === "#") {
event.preventDefault();
}
if ($(this).attr('aria-expanded') === "true") {
console.log("ppppp");
$(this).attr('aria-expanded', false);
$(this).removeClass('is-opened');
EltToToggle.removeClass('show');
console.log("click true")
} else if ($(this).attr('aria-expanded') === "false") {
$(this).attr('aria-expanded', true);
$(this).addClass('is-opened');
EltToToggle.addClass('show');
console.log("click false")
}
});
}
click_item();
$(document).mouseup(function(e) {
var sub_menu = $(".sub-menu");
// If the target of the click isn't the sub_menu
if (!sub_menu.is(e.target) && sub_menu.has(e.target).length === 0) {
sub_menu.removeClass('show');
$(".menu-item-has-children > a").attr('aria-expanded', false);
$(".menu-item-has-children > a").removeClass('is-opened');
console.log("ok")
}
click_item();
});
.menu {
display: flex;
}
li {
margin: 10px;
}
.sub-menu {
display: none;
position: absolute;
top: auto;
left: 50%;
-webkit-transform: translate(-50%, 2rem);
transform: translate(-50%, 2rem);
padding: 1rem 0;
background-color: #fff;
border-radius: .6rem;
box-shadow: 0 1rem 2rem rgba(0, 0, 0, .1);
}
.show {
display: block!important;
}
.menu-item-has-children>a {
position: relative
}
.menu-item-has-children>a:after {
top: 2rem;
right: 1.5rem;
}
.menu-item-has-children>a:after {
content: "\f077";
font-family: FontAwesome!important;
font-style: normal;
font-weight: 400;
font-variant: normal;
text-transform: none;
line-height: 1;
font-size: inherit;
display: inline-block;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-alt: "";
speak: none;
right: 1.6rem;
top: 2.3rem;
font-size: 1rem;
transition: -webkit-transform .25s ease;
transition: transform .25s ease;
transition: transform .25s ease,-webkit-transform .25s ease;
}
.menu-item-has-children>a:after {
top: 2rem;
right: 1.5rem;
}
.menu-item-has-children>a[aria-expanded=true]:after {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false" class="">
Item 1
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl2. Children 1
</a>
</li>
<li class="menu-item">
<a href="#">
Lvl2. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false">
Link 2
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#">
Lvl3. Children 1
</a>
</li>
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl3. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl3. Children 3
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl2. Children 4
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false" class="">
Link 2
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl2. Children 1
</a>
</li>
<li class="menu-item">
<a href="#">
Lvl2. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false">
Lvl2. Children 3 with children
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#">
Lvl3. Children 1
</a>
</li>
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl3. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl3. Children 3
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl2. Children 4
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
</ul>
Try to hide/show your navigation bar using css class, that will be easy and effective way to manage it.
Also replace $(document).mouseup with $(document).click, you just need clicking event, so I recommend to avoid using mouseup in such scenarios.
You can do something like this:
$(document).ready(function() {
$(document).click(function(event) {
var clickover = $(event.target);
// if the user click outside navbar
if (!clickover.hasClass("navbar")) {
$(".navbar").removeClass("in");
}
});
});
.navbar.in {
background: red;
width: 100px;
height: 100%;
position: absolute;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Demo Test</title>
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
</head>
<body>
<div class="navbar in"></div>
</body>
</html>
Click outside the navbar and it'll be closed. This is just a DEMO that can help you understand how to hide/show elements by clicking events.
Here is a solution
If there are no submenus, close all parent uls with class show
I also converted the if to a toggle
$('.menu-item-has-children a').on('click', function() {
var EltToToggle = $(this).next('.sub-menu');
if ($(this).attr('href') === "#") {
event.preventDefault();
}
const expanded = $(this).attr('aria-expanded') === "true"
$(this).attr('aria-expanded', !expanded);
$(this).toggleClass('is-opened', !expanded);
EltToToggle.toggleClass('show', !expanded);
if (EltToToggle.length === 0) {
$(this).parents("ul,show").toggleClass("show",false)
}
});
$(document).mouseup(function(e) {
var sub_menu = $(".sub-menu");
// If the target of the click isn't the sub_menu
if (!sub_menu.is(e.target) && sub_menu.has(e.target).length === 0) {
sub_menu.removeClass('show');
$(".menu-item-has-children > a").attr('aria-expanded', false);
$(".menu-item-has-children > a").removeClass('is-opened');
console.log("ok")
}
});
.menu {
display: flex;
}
li {
margin: 10px;
}
.sub-menu {
display: none;
position: absolute;
top: auto;
left: 50%;
-webkit-transform: translate(-50%, 2rem);
transform: translate(-50%, 2rem);
padding: 1rem 0;
background-color: #fff;
border-radius: .6rem;
box-shadow: 0 1rem 2rem rgba(0, 0, 0, .1);
}
.show {
display: block!important;
}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false" class="">
Item 1
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl2. Children 1
</a>
</li>
<li class="menu-item">
<a href="#">
Lvl2. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false">
Link 2
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#">
Lvl3. Children 1
</a>
</li>
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl3. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl3. Children 3
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl2. Children 4
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false" class="">
Link 2
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl2. Children 1
</a>
</li>
<li class="menu-item">
<a href="#">
Lvl2. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item menu-item-has-children">
<a href="#" aria-expanded="false">
Lvl2. Children 3 with children
</a>
<ul class="sub-menu">
<li class="menu-item">
<a href="#">
Lvl3. Children 1
</a>
</li>
<li class="menu-item">
<a href="#" aria-current="page">
[Current] Lvl3. Children 2 with long text lorem ipsum
</a>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl3. Children 3
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
<li class="menu-item">
<a href="#" target="_blank" class="external-link">
[_blank] Lvl2. Children 4
<span class="icon-link-external" aria-hidden="true"></span></a>
</li>
</ul>
</li>
</ul>
try this
$(document).ready(function(){
$("*").click(function(){
$(".menu-item-has-children > a").removeClass('is-opened');
});
});
First of all here's the code - http://plnkr.co/edit/Iq9bjzCljALHORYIRvhe?p=preview
Now, as you can see there are two parts - the sidebar title, with the red background color, and the sidebar items, which are with the black background color.
Now, what I'm trying to get is to make the scroll available only at the black background part of the sidebar, meaning the red title is fixed.
How may I do this?
here's the html code -
<html ng-app="app">
<head>
<script data-require="angular.js#1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div class="container">
<div ng-controller="SidebarController">
Navigation
<div class="sidebar" sidebar-directive="state">
<div class="topmenu">Menu</div>
<ul class="navigation">
<li class="navigation-items"> Link1
</li>
<li class="navigation-items"> Link2
</li>
<li class="navigation-items"> Link3
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
<li class="navigation-items"> Link4
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
and here's the css code -
body {
font-family: arial;
}
.sidebar {
position: absolute;
top: 0;
left: -160px;
transition: 100ms left;
height: 100%;
overflow-y: auto;
}
#navigation-toggle {
position: absolute;
left: 160px;
background: rgba(3, 159, 244, .95);
color: white;
text-decoration: none;
padding: 20px;
}
.show {
left: 0;
}
.navigation {
list-style: none;
padding: 0;
margin: 0;
}
.navigation-items a {
display: block;
background-color: #444;
color: white;
line-height: 2em;
text-decoration: none;
padding: 10px 30px;
width: 100px;
}
.navigation-items a:hover {
background-color: #222;
}
.topmenu {
background-color: #f00;
height: 70px;
}
Ok, now I'm see. I update your plunker. See it working:
http://plnkr.co/edit/SwyhsdfeJtaNX7WU0Kao?p=preview
The changes are so simple:
.sidebar {
overflow:hidden;
}
.navigation: {
height: calc(100% - 70px);
overflow:auto;
}
And that's all.
Your CSS:
.sidebar {
position :fixed;
top : 0;
left : -160px;
transition : 100ms left;
border: 1px solid #f00;
height : 100%;
}
.navigation {
list-style : none;
padding : 0;
margin : 0;
height:100%;
overflow-y:scroll;
}
http://plnkr.co/edit/AUzowwf0AOC9U7QLUlOW?p=preview
Hello I want to know if it was possible to expand the bootstrap navbar when I click on a dropdown menu ? please
before click:
+------------------------------------------------+
| THE NAVBAR - dropdown menu \/ |
+------------------------------------------------+
after click:
+------------------------------------------------+
| THE NAVBAR - dropdown menu \/ |
| submenu |
+------------------------------------------------+
This might be helpful as an example. It's relatively straight forward once you look into the CSS. There are also libraries like Yamm!3.
.navbar-default {
border-bottom: 4px solid #f00 !important;
background: #fff !important;
}
.navbar-default .navbar-nav > li > a,
.navbar-header a.navbar-brand {
color: #f00;
}
.navbar-default .navbar-nav > .dropdown > a .caret {
border-top-color: #f00;
border-bottom-color: #f00;
}
.menu-large {
position: static !important;
}
.megamenu {
padding: 20px 0px;
width: 100%;
}
.megamenu> li > ul {
padding: 0;
margin: 0;
}
.megamenu> li > ul > li {
list-style: none;
}
.megamenu> li > ul > li > a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 1.428571429;
color: #f00;
white-space: normal;
}
.megamenu> li ul > li > a:hover,
.megamenu> li ul > li > a:focus {
text-decoration: none;
color: #262626;
background-color: #f5f5f5;
}
.megamenu.dropdown-header {
color: #428bca;
font-size: 18px;
}
.megamenu img {
width: 100%;
height: 150px;
padding: 5px;
}
#media (max-width: 768px) {
.megamenu {
margin-left: 0;
margin-right: 0;
}
.megamenu> li {
margin-bottom: 30px;
}
.megamenu> li:last-child {
margin-bottom: 0;
}
.megamenu.dropdown-header {
padding: 3px 15px !important;
}
.navbar-nav .open .dropdown-menu .dropdown-header {
color: #fff;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<div class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button> <a class="navbar-brand" href="#">Brand</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li>Home
</li>
<li class="dropdown menu-large"> Stuff <span class="caret"></span>
<ul class="dropdown-menu megamenu row ">
<li>
<div class="col-sm-6 col-md-3 ">
<a href="# " class="img-responsive ">
<img src="http://placehold.it/300/f00/fff" />
</a>
</div>
<div class="col-sm-6 col-md-3 ">
<a href="# " class="img-responsive ">
<img src="http://placehold.it/300/f00/fff" />
</a>
</div>
<div class="col-sm-6 col-md-3 ">
<a href="# " class="img-responsive ">
<img src="http://placehold.it/300/f00/fff" />
</a>
</div>
<div class="col-sm-6 col-md-3 ">
<a href="# " class="img-responsive ">
<img src="http://placehold.it/300/f00/fff" />
</a>
</div>
</li>
</ul>
</li>
<li class="dropdown menu-large "> Things <span class="caret"></span>
<ul class="dropdown-menu megamenu row ">
<li class="col-sm-3 ">
<ul>
<li class="dropdown-header ">Item I Main</li>
<li>Item I Sub
</li>
<li class="disabled ">Item II Sub
</li>
<li>Item III Sub
</li>
<li class="divider "></li>
<li class="dropdown-header ">Item II Main</li>
<li>Item I Sub
</li>
<li>Item II Sub
</li>
<li>Item III Sub
</li>
<li>Item VI Sub
</li>
</ul>
</li>
<li class="col-sm-3 ">
<ul>
<li class="dropdown-header ">Item III Main</li>
<li>Item I Sub
</li>
<li>Item II Sub
</li>
<li>Item III Sub
</li>
<li>Item VI Sub
</li>
<li>Item V Sub
</li>
<li class="divider "></li>
<li class="dropdown-header ">Item IV Main</li>
<li>Item I Sub
</li>
</ul>
</li>
<li class="col-sm-3 ">
<ul>
<li class="dropdown-header ">Item V Main</li>
<li>Item I Sub
</li>
<li>Item II Sub
</li>
<li>Item III Sub
</li>
<li class="divider "></li>
<li class="dropdown-header ">Item VI Main</li>
<li>Item I Sub
</li>
<li>Item II Sub
</li>
<li>Item III Sub
</li>
</ul>
</li>
<li class="col-sm-3 ">
<ul>
<li class="dropdown-header ">Item VII Main</li>
<li>Item I Sub
</li>
<li>Item II Sub
</li>
<li>Item III Sub
</li>
<li>Item VI Sub
</li>
<li>Item V Sub
</li>
<li>Item VI Sub
</li>
<li>Item VII Sub
</li>
<li>Item VIII Subp
</li>
<li>Item VIIII Sub
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
Try using bootstrap collapse like this:
.my-menu{
padding: 10px;
}
#collapse-menu{
margin-bottom: 0;
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<nav class="navbar navbar-default my-nav-bar" role="navigation">
<a class="navbar-brand" href="#">Logotipo</a>
<div class="pull-right my-menu">
<button href="#" class="dropdown-toggle btn btn btn-primary" data-toggle="collapse" data-target="#collapse-menu"> <!--add the atributes data-toggle="collapse" data-target="#collapse-menu" to the element that you want to be the collapser-->
Dropdown Menu <b class="caret"></b>
</button>
<ul id="collapse-menu" class="list-group collapse"> <!--add the class "collapse" to the element that you want collapse-->
<li class="list-group-item">Acción #1</li>
<li class="list-group-item">Acción #2</li>
</ul>
</div>
</nav>