Nested Menus Using Jquery and CSS - javascript

I am trying to create a nested navigation menu using jquery and css.
Currently my nav is hosted on xetecx.comxa.com. The problem is that the nested submenus don't shift towards the right on the main menu like a proper nested menu as shown in this video.
https://drive.google.com/file/d/0B0sCu8aj8zu2UzBxQnVlQWdzcUU/edit?usp=sharing
If you click on menu on xetecx.comxa.com
Here is my html
<ul>
<li>
<img src="img/main.png" />
<ul>
<li>
Retails
<ul>
<li>
R
</li>
<li>
S
</li>
<li>
A
</li>
<li>
C
</li>
</ul>
</li>
<li>
Services
</li>
<li>
About Us
</li>
<li>
Contact Us
<ul>
<li>
R
</li>
<li>
S
</li>
<li>
A
</li>
<li>
C
</li>
</ul>
</li>
</ul>
</li>
<li>
<img src="img/social.png" />
<ul class="social">
<li>
<img src="img/facebook.png" />
</li>
<li>
<img src="img/twitter.png" />
</li>
<li>
<img src="img/linked.png" />
</li>
</ul>
</li>
</ul>
And My Jquery
(function($) {
//cache nav
var nav = $("#topNav");
//add indicators and hovers to submenu parents
nav.find("li").each(function() {
if ($(this).find("ul").length > 0) {
$("<span>").appendTo($(this).children(":first"));
//show subnav on hover
$(this).mouseenter(function() {
var ullist = $(this).find("ul");
ullist.stop(true, true).slideDown();
ullist.addClass("ullist");
});
//hide submenus on exit
$(this).mouseleave(function() {
var ullist = $(this).find("ul");
ullist.stop(true, true).slideUp();
ullist.removeClass("ullist");
});
}
});
})(jQuery);
And the CSS I tried to use to solve the problem
nav > ul > li > a > img {
width:60px;
height:60px;
}
.social li > a > img{
width:40px;
height:40px;
}
But it is not working out for me.

Have you tried changing the css for
nav ul ul ul
which should have left as some 100px;
so
.nav ul ul ul
{
left:100px;
}

Related

How can I select all the li child of an element in js

How can I select all the li child of an element in js
I want to select all the li elements of this item (direct child, grand child all)
document.querySelectorAll(".stellarnav li.has-sub").forEach(item =>{
item.addEventListener("click", function(){
console.log(item)
// to make you understand I described it below in css language
// in CSS language it is like this: item li
// then I want to removeAttribute from the all the child
// like this
document.querySelectorAll(`${item} li`).forEach(childItem =>{
childItem.removeAttribute("open");
})
// how can I achive this thing to select all the li childs
// here I tried it but this is not valid
})
});```
Just run this.querySelectorAll('li').forEach(li=>li.removeAttribute("open"));
This is a document querySelectorAll document
Tested code:
document.querySelectorAll(".nav li.has-sub").forEach(item =>{
item.addEventListener("click", function(){
this.querySelectorAll('li').forEach(li=>li.removeAttribute("open"));
})
})
li[open]{
color: red;
}
.nav >li{
margin: 10px
}
<ul class='nav'>
<li class='has-sub'>
this is has-sub li 1
<ul>
<li open>
this is open
</li>
<li open>
this is open
</li>
<li> this is another li
</li>
</ul>
</li>
<li class='has-sub'>
this is has-sub li 2
<ul>
<li open>
this is open
</li>
<li open>
this is open
</li>
<li> this is another li
</li>
</ul>
</li>
<li>
this is li 3
<ul>
<li open>
this is not has-sub open
</li>
<li open>
this is not has-sub open
</li>
<li> this is another li
</li>
</ul>
</li>
</ul>

Change background list item on click in dynamic nested List

I have nested lists draw in run time dynamic from database in away like this :
<div class="list"><ul>
<li>
listA
<ul>
<li>Alist1</li>
<li>Alist2</li>
<li>Alist3</li>
</ul>
</li>
<li>
listB
<ul>
<li>BList1</li>
<li>BList2</li>
<li>BList3</li>
</ul>
</li>
i want to change the back ground of list item when clicked but it change style of the all nested list by the following method :
var $li = $('#list li').click(function () {
$li.removeClass('selected');
$(this).addClass('selected');
});
using this style :
li.selected {
background-color: aqua;}
I know that i should use the direct descendant operator (>) to force change to parent only but my problem that list is drawn dynamically and I can't limit its levels and nested list.
is there away to always force only clicked item to be changed only ?
1- You can't use #list while your list have a class list not id list with classes you need to use dot not #
2- You need to use > like $('.list > ul > li')
$(document).ready(function(){
$('ul > li').on('click' , function(e){
e.stopPropagation();
//$('li > ul').hide();
$(this).find(' > ul').slideDown();
$(this).parent('ul').find('li').removeClass('selected');
$(this).addClass('selected');
});
});
ul{
background : #fff;
}
li > ul{
display : none;
}
li.selected{
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list">
<ul>
<li>
listA
<ul>
<li>Alist1
<ul>
<li>Alist1-1</li>
<li>Alist1-2</li>
<li>Alist1-3</li>
</ul>
</li>
<li>Alist2</li>
<li>Alist3</li>
</ul>
</li>
<li>
listB
<ul>
<li>BList1</li>
<li>BList2</li>
<li>BList3</li>
</ul>
</li>
</ul>
</div>
-- It'll be better to work with <a> see the next example
$(document).ready(function(){
$('a').on('click' , function(e){
e.preventDefault();
var GetLi = $(this).closest('li');
var GetBigUL = $(this).closest('ul');
var GetNextUL = $(this).next('ul');
GetBigUL.find('a').next('ul').not(GetNextUL).slideUp();
GetNextUL.slideDown();
GetBigUL.find('li').removeClass('selected');
GetLi.addClass('selected');
});
});
ul{
background : #fff;
}
li > ul{
display : none;
}
li.selected{
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list">
<ul>
<li>
<a>listA</a>
<ul>
<li>
<a>Alist1</a>
<ul>
<li><a>Alist1-1</a></li>
<li><a>Alist1-2</a></li>
<li><a>Alist1-3</a></li>
</ul>
</li>
<li><a>Alist2</a></li>
<li><a>Alist3</a></li>
</ul>
</li>
<li>
<a>listB</a>
<ul>
<li><a>BList1</a></li>
<li><a>BList2</a></li>
<li><a>BList3</a></li>
</ul>
</li>
</ul>
</div>

How to toggle <li> in a nested list?

I'm trying to be able to toggle these sub menus one at a time, I'm getting lost in nests and cant quite figure out how to target the correct list item,
I found that I should be using find() instead of children() as it can go deeper in the nest but still no luck in getting it working.
<ul>
<li>Profile</li>
<li>Edit</li>
<li class="drop-nav"> See your products
<ul>
<li class="drop-nav"> Mens
<ul>
<li> jumpers </li>
<li> t shirts </li>
</ul>
</li>
<li class="drop-nav"> Womens
<ul>
<li> hoodies </li>
<li> leggings </li>
</ul>
</li>
</ul>
</li>
</ul>
$(".drop-nav").on("click", function(e){
e.preventDefault();
});
li ul{
display: none;
}
You could use $(this).find('ul').eq(0) to get the ul, but I would delegate the changing of the display to the stylesheet, but use javascript to add a class where applicable. This will give you many more options for the design of your dropdown later.
$(".drop-nav").on("click", function(e) {
e.preventDefault()
// don't allow the event to fire horizontally or vertically up the tree
e.stopImmediatePropagation()
// switch the active class that you can use to display the child
$(this).toggleClass('active')
})
/* don't target ll list items in you page, be more specific */
.drop-nav > ul {
display: none;
}
.drop-nav.active > ul {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Profile</li>
<li>Edit</li>
<li class="drop-nav"> See your products
<ul>
<li class="drop-nav"> Mens
<ul>
<li> jumpers </li>
<li> t shirts </li>
</ul>
</li>
<li class="drop-nav"> Womens
<ul>
<li> hoodies </li>
<li> leggings </li>
</ul>
</li>
</ul>
</li>
</ul>
I would add more descriptive class names in your markup, and make them easier to target with CSS and jQuery.
To toggle the menus you could do something like the following:
$(".dropdown-trigger1").on("click", function() {
// Toggle the first menu
$(".dropdown-one").toggleClass("open");
// Close the submenus
$(".dropdown-two").removeClass("open");
});
$(".dropdown-trigger2").on("click", function(e) {
// Prevent a click on a submenu from closing the menu
e.stopPropagation();
// Close any open submenu
$(".dropdown-two").removeClass("open");
// Open the submenu that has been clicked
$(this).find(".dropdown-two").toggleClass("open");
});
li ul {
display: none;
}
.dropdown-one.open {
display: block;
}
.dropdown-two.open {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Profile</li>
<li>Edit</li>
<li class="dropdown-trigger1"> See your products
<ul class="dropdown-one">
<li class="dropdown-trigger2"> Mens
<ul class="dropdown-two">
<li> jumpers </li>
<li> t shirts </li>
</ul>
</li>
<li class="dropdown-trigger2"> Womens
<ul class="dropdown-two">
<li> hoodies </li>
<li> leggings </li>
</ul>
</li>
</ul>
</li>
</ul>
You haven't described about how you activate each sub-menu, so I will describe solution little bit abstractly. Solution is based on your HTML structure an will work if you wouldn't change it.
$('.drop-nav a').on('click', function() {
// This next method returns next element in DOM that is after clicked a link.
// Based on your HTML it would be ul that holds your sub-menu.
var subMenu = $(this).next();
// Here using subMenu selector to make something with sub-menu...
// Example: adding CSS inline to sub. In your situation it may be something else...
$(subMenu).css({ 'display' : 'block' });
});

onclick expand multiple menu

I want to make an onclick expand multiple menu in my website
Before I follow this thread: this with little bit modify I get:
<ul>
<rg><li id="auctions">Menu</li></rg>
<br></br>
<lf>
<li class="submenu">Left</li>
</lf>
<rg>
<li class="submenu">Right</li>
</rg>
</ul>
But it only shows a menu, then I create a duplicate like this:
<ul>
<rg><li id="auctions">Menu</li></rg>
<br></br>
<lf>
<li class="submenu">Left</li>
</lf>
<rg>
<li class="submenu">Right</li>
</rg>
</ul><ul>
<rg><li id="auctions2">Menu</li></rg>
<br></br>
<lf>
<li class="submenu2">Left</li>
</lf>
<rg>
<li class="submenu2">Right</li>
</rg>
</ul>
And JS and CSS like this:
<script>
$(function() {
$('#auctions').click(function(){
$('.submenu').slideToggle();
});
});
$(function() {
$('#auctions2').click(function(){
$('.submenu2').slideToggle();
});
});
</script>
<style>
.submenu{display:none;}
.submenu2{display:none;}
rg {float:right}
lf {float:left}
</style>
Its work but doesn't run inline. Then I useul {display:inline-block}
Yes, the menu running inline, but it's broken and float doesn't work properly. Can it's fixed? or can I make multiple menu in same <ul>?
make rg and lf as classes and change the html accordingly to get your desired style.
But I recommend, you should consider studying about ul and li tags and its properties before using it
$(function() {
$('#auctions').click(function() {
$('.submenu').slideToggle();
});
});
$(function() {
$('#auctions2').click(function() {
$('.submenu2').slideToggle();
});
});
ul {
display: block;
margin:0;
padding:0;
width:100%;
}
li {
list-style: none;
}
li.main {
width:100%;
text-align:right;
}
.submenu {
display: none;
}
.submenu2 {
display: none;
}
.rg {
float: right;
}
.lf {
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<ul>
<li id="auctions" class="main rg">Menu</li>
<li>
<ul>
<li class="submenu lf">Left</li>
<li class="submenu rg">Right</li>
</ul>
</li>
</ul>
</li>
<li>
<ul>
<li id="auctions2" class="main rg">Menu</li>
<li>
<ul>
<li class="submenu2 lf">Left</li>
<li class="submenu2 rg">Right</li>
</ul>
</li>
</ul>
</li>
</ul>

need help for javascript menu for "menuTrigger"

need your help for menuTrigger javascript
I am making menu like, firstly display only titles but when clicked on menu icon(which right now dark grey box) it expands with further submenus.
I have almost achieved what I want, but (stuck)I want fade effect or animation effect when clicking on menu button to open menu.Which I am not getting proper syntax to put, plz do help me with that achieving effect.
You can check code on link:
http://jsfiddle.net/kBpqa/1/
JS:
(function ($) {
$(document).ready(function() {
/* --------- Main Submenu Open/Close --------- */
var menuOpen = false;
// Close menu when pointer leaves expanded menu
$('#headerContainer').mouseleave(
function() {
if( menuOpen == true)
closeSubMenu();
});
// Open/Close menu when user clicks on trigger link
$('.menuTrigger').click(
function(e){
e.preventDefault();
if( menuOpen == true)
closeSubMenu();
else
openSubMenu();
});
// Opens Main Submenu
function openSubMenu(){
$('#mainMenu').addClass('openMenu');
$('#mainMenu').find('ul.menu li ul').show();
var menuHeight = $('#mainMenu').height();
$('#header').height(menuHeight);
$('#mainMenu').find('ul.menu li ul').delay(300).css({'opacity' : 1});
$('#header .extIcons').show(500);
// $('#header .extIcons a').delay(500).css({'opacity' : 1});
// contractLogo();
if ( $(window).width() < 1400 ) {
$('#logo a').html('');
};
menuOpen = true;
}
// Closes Main Submenu
function closeSubMenu(){ $('#mainMenu').removeClass('openMenu');
$('#mainMenu').find('ul.menu li ul').css({'opacity' : 0});
$('#mainMenu').find('ul.menu li ul').delay(500).hide();
var menuHeight = $('#mainMenu').height();
$('#header .extIcons').hide();
$('#header').height(menuHeight);
// contractLogo();
$('#logo a').text('');
menuOpen = false;
}
/* --------- END Main Submenu Open/Close --------- */
});
}
(jQuery));;
HTML:
<div id="header">
<div id="headerContainer">
<div class="block block-menu-block">
<div id="mainMenu">
<ul class="menu">
<li class="first expanded menu-mlid-601 menu-601">About Us
<ul class="menu">
<li class="first leaf menu-mlid-606 menu-606">Title1</li>
<li class="leaf menu-mlid-585 menu-585">Title2</li>
<li class="leaf has-children menu-mlid-1409 menu-1409">Title3</li>
<li class="leaf has-children menu-mlid-616 menu-616">Title4</li>
</ul>
</li>
<li class="expanded active-trail active menu-mlid-1107 menu-1107">Work
<ul class="menu">
<li class="first leaf menu-mlid-1138 menu-1138">Title1</li>
<li class="leaf menu-mlid-1134 menu-1134">Title1</li>
<li class="leaf menu-mlid-1137 menu-1137">Title1</li>
<li class="leaf menu-mlid-1135 menu-1135">Title1 </li>
<li class="leaf menu-mlid-1260 menu-1260">Title1</li>
<li class="leaf menu-mlid-1261 menu-1261">Title1</li>
</ul>
</li>
<li class="expanded menu-mlid-1237 menu-1237">Research
<ul class="menu">
<li class="first leaf menu-mlid-1138 menu-1138">Title1</li>
<li class="leaf menu-mlid-1134 menu-1134">Title1</li>
<li class="leaf menu-mlid-1137 menu-1137">Title1</li>
<li class="leaf menu-mlid-1135 menu-1135">Title1 </li>
<li class="leaf menu-mlid-1260 menu-1260">Title1</li>
<li class="leaf menu-mlid-1261 menu-1261">Title1</li>
</ul>
</li>
<li class="expanded menu-mlid-1103 menu-1103">Current Events
<ul class="menu">
<li class="first leaf menu-mlid-1138 menu-1138">Title1</li>
<li class="leaf menu-mlid-1134 menu-1134">Title1</li>
<li class="leaf menu-mlid-1137 menu-1137">Title1</li>
<li class="leaf menu-mlid-1135 menu-1135">Title1 </li>
<li class="leaf menu-mlid-1260 menu-1260">Title1</li>
<li class="leaf menu-mlid-1261 menu-1261">Title1</li>
</ul>
</li>
<li class="last expanded menu-mlid-1105 menu-1105">Contact</li>
</ul>
<div class="menuTrigger">Menu</div>
</div>
</div>
</div><!-- end headerContainer -->
</div><!-- end header -->
CSS:
div.block-menu-block{float:right; margin-top:0px;background-color: #e7e7e7;}
#headerContainer{background-color:#e7e7e7;}
#mainMenu{margin:0;padding:0;overflow:auto;}
#mainMenu > ul{margin:0;margin-right:65px;padding:0;list-style-type:none;}
#mainMenu li{margin:0;position:relative;}
#mainMenu > ul > li > a{color:#111 !important;display:block;padding:1.6em 1em;font-weight:600; font-size:17px;}
#header a:hover{color:#111 !important;}
#mainMenu > ul > li{float:left;}
div.menuTrigger{padding:.8em 1em 0 0;margin:0;float:right;background:#ccc}
.menuTrigger a{width:40px;height:40px;text-indent:9999em;display:block;overflow:hidden;margin-top:6px;background:url(../images/menu-trigger.png) no-repeat;}
.menuTrigger a:hover{background-position:0 -40px;}
#mainMenu > ul > li > ul{margin:0 3em 3em 1.5em !important;padding:0;display:none; font-size:13px; line-height:1.2em;}
#mainMenu > ul > li > ul > li{max-width:9em;padding:.4em 0;font-size:1em !important;display:block;}
#menu .first leaf menu-mlid-606 menu-606 a{ font-size:14px;}
#mainMenu > ul > li > ul > li > a{font-weight:normal;color:#999 !important;}
li.current{background:#222222;float:left;}
You can use slideDown() or slideUp() instead of hide() function. And you can user fadeIn() instead of .dealy(500).css({opacity:1}) . To make your animation more smooth you can you easing in jquery for most of the functions.
Updated fiddle
You can use jquery slideToggle() for this. check this fiddle: fiddle
$('#mainMenu').find('ul.menu li ul').slideToggle('slow');

Categories