Multilevel sidebar menu using JS/jquery - javascript

I need to have a responsive sidebar navigation (as part of making the website responsive) for a multilevel menu of depth 3. The html markup is as below,
<nav>
<div data-level="1">
<ul>
<li class="main-menu">
Level1
<div data-level="2">
<ul>
<li class="submodule">
example1.1
<div data-level="3">
<ul>
<li>example1.1.1</li>
<li>example1.1.2</li>
<li>example1.1.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.2
<div data-level="2">
<ul>
<li>example1.2.1</li>
<li>example1.2.2</li>
<li>example1.2.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.3
<div data-level="2">
<ul>
<li>example1.3.1</li>
<li>example1.3.2</li>
<li>example1.3.3</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li>
Level2
<div data-level="2">
<ul>
<li>
example2.1
<div data-level="3">
<ul>
<li>example2.1.2</li>
<li>example2.1.3</li>
<li>example2.1.4</li>
</ul>
</div>
</li>
<li>
example2.2
<div data-level="2">
<ul>
<li>example2.2.1</li>
<li>example2.2.2</li>
<li>example2.2.3</li>
</ul>
</div>
</li>
<li>
example2.3
<div data-level="2">
<ul>
<li>example2.3.1</li>
<li>example2.3.2</li>
<li>example2.3.4</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</nav>
At first menu shows only the top level,
Level1
Level2
When Level1 is clicked menu should show,
Back to Main Menu
example 1.1
example 1.2
When example1.1 is clicked,
Back to sublevel
example1.1.1
example1.1.2
example1.1.3
Each of back button takes to the menu before.
How to do the navigation using JS/jQuery?

It was necessary to adjust your navigation a little bit - the navigation for Level 2 was missing the submodule class. In addition you could consider to adjust your usage of <div data-level="3"> as you only use it for the 2nd and 3rd sublevel navigation while the 1st sublevel is in a <div data-level="2">. The following navigation fulfills your requirements while it is not complete - you can adjust it so a visible sublevel navigation gets toggled when the main navigation gets clicked. I already took care about the issue to only have one main navigation and submodule navigation visible at the same time.
$(".main-menu").on("click", function() {
if ($(".main-menu").not(this).find(".submodule").is(":visible")) {
$(".main-menu").not(this).find(" > div[data-level='2'], .submodule").hide();
}
$(this).find(" > div[data-level='2'], .submodule").toggle();
});
$(".submodule").on("click", function(e) {
e.stopPropagation();
$(".submodule").not(this).each(function() {
if ($(this).find(" > div[data-level='3'], > div[data-level='2']").is(":visible")) {
$(this).find(" > div[data-level='3'], > div[data-level='2']").hide();
}
});
$(this).find(" > div[data-level='3'], > div[data-level='2']").toggle();
});
$(".submodule.back").on("click", function(e) {
e.stopPropagation();
$(this).closest(".main-menu").find(" > div[data-level='2'], .submodule").hide();;
});
$(".back").not(".submodule").on("click", function(e) {
e.stopPropagation();
$(this).closest(".submodule").find(" > div[data-level='3'], > div[data-level='2']").hide();
});
div[data-level ="2"]{
display:none;
}
div[data-level ="3"]{
display:none;
}
.submodule {
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<div data-level="1">
<ul>
<li class="main-menu">
Level1
<div data-level="2">
<ul>
<li class="submodule back">
Back to main menu
</li>
<li class="submodule">
example1.1
<div data-level="3">
<ul>
<li class="back">Back to sublevel</li>
<li>example1.1.1</li>
<li>example1.1.2</li>
<li>example1.1.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.2
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example1.2.1</li>
<li>example1.2.2</li>
<li>example1.2.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.3
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example1.3.1</li>
<li>example1.3.2</li>
<li>example1.3.3</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li class="main-menu">
Level2
<div data-level="2">
<ul>
<li class="submodule back">
Back to main menu
</li>
<li class="submodule">
example2.1
<div data-level="3">
<ul>
<li class="back">Back to sublevel</li>
<li>example2.1.2</li>
<li>example2.1.3</li>
<li>example2.1.4</li>
</ul>
</div>
</li>
<li class="submodule">
example2.2
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example2.2.1</li>
<li>example2.2.2</li>
<li>example2.2.3</li>
</ul>
</div>
</li>
<li class="submodule">
example2.3
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example2.3.1</li>
<li>example2.3.2</li>
<li>example2.3.4</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</nav>

Related

Navbar dropdown moving to extreme left after putting $('#header').load('header.html') script

My navbar dropdown is moving towards the extreme left and also not opening properly after adding this script, when i remove the script and run it like a normal static html page it is running completely fine, Please help if you can, it would save me a lot of time in this
$(function() {
$('#header').load('header.html');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
</script>
</script>
HERE IS HTML OF MY NAVBAR
<header class="header-area">
<div class="main-header-area">
<div class="classy-nav-container breakpoint-off">
<div class="container">
<!-- Classy Menu -->
<nav class="classy-navbar justify-content-between" id="robertoNav">
<!-- Logo -->
<a class="nav-brand" href="#"><img src="./img/core-img/logo.png" alt=""></a>
<!-- Navbar Toggler -->
<div class="classy-navbar-toggler">
<span class="navbarToggler"><span></span><span></span><span></span></span>
</div>
<!-- Menu -->
<div class="classy-menu">
<!-- Menu Close Button -->
<div class="classycloseIcon">
<div class="cross-wrap"><span class="top"></span><span class="bottom"></span></div>
</div>
<!-- Nav Start -->
<div class="classynav">
<ul id="nav">
<li class="active">Home</li>
<li>About Us</li>
<li>Products
<ul class="dropdown">
<li>Item
<ul class="dropdown">
<li>Dropdown</li>
<li>Dropdown</li>
<li>Dropdown</li>
</ul>
</li>
<li>-Double Width Tower
<ul class="dropdown">
<li>Dropdown</li>
<li>Dropdown</li>
</ul>
</li>
<li>Item</li>
<li>Item
<ul class="dropdown">
<li>dropdow</li>
<li>dropdown</li>
<li>dropdown</li>
</ul>
</li>
<li>-other accessories
<ul class="dropdown">
<li>dropdown</li>
</ul>
</li>
</ul>
</li>
<li>Ladders
<ul class="dropdown">
<li>dropdown</li>
<li>dropdown</li>
<li>dropdown</li>
</ul>
</li>
<li>Accessories
<ul class="dropdown">
<li>- dropdown</li>
<li>- dropdown Item</li>
<li>- dropdown</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
<!-- Nav End -->
</div>
</nav>
</div>
</div>
</div>
</header>

Change font color on scroll for nav items

I want to change my nav elements from white to gray but I get the error
cannot set property 'color' of undefined.
I have some javascript that pushes the nav up so it's hidden on a down scroll, but I need the color of the elements to change from white to gray.
window.addEventListener("scroll",function() {
var el = $('#landingImage');
var heroBottom = el.position().top + el.outerHeight(true);
if(window.scrollY > heroBottom - 3) {
$('.item').style.color='white';
}
else {
$('.item').style.color='#7d7d7d';
}
},false);
This is HTML
<div id="landingImage">
<nav id="nav">
<ul class="menu">
<li class="logo"><img src="logo.png" height="100px"></li>
<li class="item">
Services <i class="arrow down"></i>
<ul>
<li>App Development</li>
<li>Web Design</li>
<li>UX Design</li>
</ul>
</li>
<li class="item">
Portfolio
</li>
<li class="item">
About
</li>
<li class="item button">
Contact
</li>
<li class="toggle"><span class="bars"></span></li>
</ul>
</nav>
<div class="header">
<h1>We design</h1>
<p>You succeed. </p>
<button type="button">Get a quote</button>
</div>
</div>
You are currently changing the text color of the .item element, which does not affect the color of the a tag inside it. Instead, you should target specifically the a tag inside the .item:
window.addEventListener("scroll", function() {
var el = $('#landingImage');
var heroBottom = el.position().top + el.outerHeight(true);
if(window.scrollY > heroBottom - 3) {
$('.item a').css("color", "white")
}
else {
$('.item a').css("color", "#7d7d7d")
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="landingImage">
<nav id="nav">
<ul class="menu">
<li class="logo"><img src="logo.png" height="100px"></li>
<li class="item">
Services <i class="arrow down"></i>
<ul>
<li>App Development</li>
<li>Web Design</li>
<li>UX Design</li>
</ul>
</li>
<li class="item">
Portfolio
</li>
<li class="item">
About
</li>
<li class="item button">
Contact
</li>
<li class="toggle"><span class="bars"></span></li>
</ul>
</nav>
<div class="header">
<h1>We design</h1>
<p>You succeed. </p>
<button type="button">Get a quote</button>
</div>
</div>
<div style="margin-top: 500px;"></div>

Unable to show the navbar in moblile view

I am stick in responsive design which i am doing in laravel. The below code works in a normal view but in the nav bar is hidden in a mobile view. I checked with the javascript function but cannot troubleshoot the problem.
This is my html code
<div class="container">
<nav>
<ul>
<li class="active">Home </li>
<li>Our School
<ul>
<li>Key Features</li>
<li>Infrastructure</li>
<li>Fee System</li>
<li>Commitment & Objectives</li>
<li>Rules & Regulations</li>
<li>Hostel Management</li>
</ul>
</li>
<li>Our Facilities </li>
<li>News & Events </li>
<li>Photo Gallery </li>
<li>Student Zone </li>
</ul>
</nav>
</div>
</div>
</div>
<!-- Mobile Menu Area Start -->
<div class="mobile-menu-area" style="display:none">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="mobile-menu">
<nav id="dopdown">
<ul>
<li>Home
<li>Our School
<ul>
<li>Key Features</li>
<li>Infrastructure</li>
<li>Fee System</li>
<li>Commitment & Objectives</li>
<li>Rules & Regulations</li>
<li>Hostel Management</li>
</ul>
</li>
<li>Our Facilities </li>
<li>News & Events </li>
<li>Photo Gallery </li>
<li>Downloads </li>
<li>Student Zone </li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
js code
$('nav#dropdown').meanmenu({siteLogo: "<a href='{{asset('client/home')}}' class='logo-mobile-menu'><img src='images/logo.png' alt='unable' /></a>"});
new WOW().init();
$.scrollUp({
scrollText: '<i class="fa fa-arrow-up"></i>',
easingType: 'linear',
scrollSpeed: 900,
animation: 'fade'
});
In the mobile view it doesn't show the header file.
The id which you gave in <nav id ='dopdown'> and which you are using in js function $(;nav#dropdown) is different.Tt may be the cause of your problem. Plese try this once.

Dropdown menu on click

I have tried numerous JS queries and none seem to be working.
I want to only show my dropdown menus when the list item they relate to is clicked, they need to show until the user either clicks off the ul or clicks a link.
Here is my html:
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<a href="#">
<li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li>
</a>
<a href="#">
<li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li>
</a>
</ul>
</div>
</div>
Try this:
$("li:has(ul)").click(function(){
$("ul",this).toggle('slow');
});
Make sure you have the jQuery library.
In this solution dropdown menus collapse when a link is clicked as you asked.
$('a').click(function(){
$('.container ul:not(:first-child)').hide();
if($(this).next().is('ul')){
$(this).next().toggle('slow');
}
});
ul ul{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<a href="#"><li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li></a>
<a href="#"><li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li></a>
</ul>
</div>
</div>
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li>
<li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li>
</ul>
</div>
</div>
this should work
Load jQuery library alternatively you can use like this.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Apply style to your menu html as below
<style>
li > ul{display:none;}
.show {display:block;}
</style>
Now this is what you are looking for.
<script>
jQuery("li:has(ul)").click(function(){
jQuery("ul",this).toggleClass('show');
});
</script>
$("li:has(ul)").click(function(){
$("ul",this).toggleClass('show');
});
li > ul{display:none;}
.show {display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<a href="#"><li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li></a>
<a href="#"><li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li></a>
</ul>
</div>
</div>
Use jQuery instead of $, because some frameworks or cms tools have conflict with it. So jQuery works always.

Combine Navigation UL jQuery Function

I am trying to write a function that will combine two children ul#level_2and append them to their parent li#level_1 within a dropdown #navigation.
I currently have the following which does the job, but it means I have to manually target each category. I'm sure there is a far shorter way to produce the same results with very little code.
$('li#furniture ul.level_2').children('li').appendTo('li#furniture ul.level_2:first');
$('li#furniture ul.level_2').children('li').not(':first').remove();
Here is a shortened version of my current html structure & below is the desired result:
Simple Current HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2">
Link A
</li>
</ul>
<ul class="level_2">
<li class="level_2">
Link B
</li>
</ul>
</div>
</li>
</ul>
</div>
Desire HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<ul class="level_2">
<li class="level_2">
Link A
</li>
<li class="level_2">
Link B
</li>
</ul>
</li>
</ul>
</div>
Full Detailed HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1 furniture">
Furniture
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 sofa">
Sofa
</li>
</ul>
<ul class="level_2">
<li class="level_2 bed">
Bed
</li>
</ul>
</div>
</li>
<li class="level_1 bathroom">
Bathroom
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 shower">
<a href="#">Shower/a>
</li>
</ul>
<ul class="level_2">
<li class="level_2 bath">
Bath
</li>
</ul>
</div>
</li>
</ul>
</div>
This should do what you need.
var wrapper = $(".subnav_wrapper").contents();
$(".subnav_wrapper").replaceWith(wrapper );
$('ul.level_2').children('li').appendTo('ul.level_2:first');
$('ul.level_2').not(':first').remove();
JSFIDDLE DEMO

Categories