Children access for a multiple li in ul - javascript

I want to change the class of ul inside the ul.navigator trying to change it only on the one li I click. But this doesn't change anything, doesn't work. some help?
$('.navigator').children('li ul').each(function() {
if ($(this).hasClass('opened')) {
$(this).addClass('closed');
$(this).removeClass('opened');
} else {
$(this).addClass('opened');
$(this).removeClass('closed');
}
});
.opened {
color: green
}
.closed {
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigator">
<li class="elem1">
<span>Element 1</span>
<ul class="opened">
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li class="elem2">
<span>Element 2 </span>
</li>
<li class="elem3">
<span>Element 3 </span>
</li>
</ul>

You need to use .find() instead of .children()
The .find() and .children() methods are similar, except that the latter only travels a single level down the DOM tree.
$('.navigator').find('li ul')
OR, Descendant selector
$('.navigator li ul')
$('.navigator').find('li ul').click(function() {
if ($(this).hasClass('opened')) {
$(this).addClass('closed');
$(this).removeClass('opened');
} else {
$(this).addClass('opened');
$(this).removeClass('closed');
}
});
.opened {
color: green
}
.closed {
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigator">
<li class="elem1">
<span>Element 1</span>
<ul class="opened">
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li class="elem2">
<span>Element 2 </span>
</li>
<li class="elem3">
<span>Element 3 </span>
</li>
</ul>

Try it like this:
$('.navigator > li').on('click', function() {
$('.navigator').children('li ul').each(function() {
if ($(this).hasClass('opened')) {
$(this).addClass('closed');
$(this).removeClass('opened');
} else {
$(this).addClass('opened');
$(this).removeClass('closed');
}
});
});
This way, when an li directly under .navigator is clicked, your code will fire.

using toggle Function
$('.navigator li').click(function(){
$(this).children('ul').toggleClass('closed');
});
Live Demo Here
snippet
$('.navigator li').click(function(){
$(this).children('ul').toggleClass('closed');
});
.closed
{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigator">
<li class="elem1">
<span>Element 1</span>
<ul class="opened">
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li class="elem2">
<span>Element 2 </span>
</li>
<li class="elem3">
<span>Element 3 </span>
</li>
</ul>

Better use with toggleClass
$('.navigator li ul').click(function(){
$(this).toggleClass('closed');
});
or
for your way to solve the problem like below:
use childern apply with same line $('.navigator li ul').
Apply removeclass before addClass.
And Don't forget to add jquery library
Snippet
$('.navigator li ul').click(function(){
if($(this).hasClass('opened')){
$(this).removeClass('opened');
$(this).addClass('closed');
} else {
$(this).addClass('opened');
$(this).removeClass('closed');
}
});
.opened{color:green}
.closed{color:red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigator">
<li class="elem1">
<span>Element 1</span>
<ul class="opened">
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li class="elem2">
<span>Element 2 </span>
</li>
<li class="elem3">
<span>Element 3 </span>
</li>
</ul>

Related

Delay on show/hide menu and submenu jQuery

I have menu and submenu:
$( ".my-menu ul li.has-children" ).on('mouseenter', function() {
$(this).children('.sub-menu').show().delay(1000).fadeOut();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="my-menu">
<ul>
<li class="has-children">
Item 1
<ul class="sub-menu">
<li>
Subitem 1
<ul class="sub-menu">
<li>EEEEE</li>
</ul>
</li>
<li>Subitem 2</li>
</ul>
</li>
<li>Item 2</li>
....
</ul>
</div>
This show submenu with delay. But when I hover on item he's hide, why? I need show menu and submenu always, when cursor on menu or submenu..
use two functions
for showing
$( ".my-menu ul li.has-children" ).on('mouseenter', function() {
$(this).children('.sub-menu').show().delay(1000);
});
for hiding
$( ".my-menu ul li.has-children" ).on('mouseleave', function() {
$(this).children('.sub-menu').fadeOut();
});
Use jQuery hover it accepts two functions: first for mouseenter and second for mouseleave. Here is an example:
$( ".my-menu ul li.has-children" ).hover(
function() {
$(this).children('.sub-menu').show()
},
function() {
$(this).children('.sub-menu').delay(1000).fadeOut();
}
);
Use mouseenter and mouseleave with fadeIn and fadeOut
Dont forget to set the .sub-menu style="display:none"
$( ".my-menu ul li.has-children" ).on('mouseenter', function() {
$(this).children('.sub-menu').fadeIn();
});
$( ".my-menu ul li.has-children" ).on('mouseleave', function() {
$(this).children('.sub-menu').fadeOut();
});
you can update like this
$( ".my-menu ul li.has-children" ).on('mouseenter', function() {
$(this).children('.sub-menu').delay(20).show();
});
$( ".my-menu ul li.has-children" ).on('mouseleave', function() {
$(this).children('.sub-menu').show().delay(20).fadeOut();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="my-menu">
<ul>
<li class="has-children">
Item 1
<ul style="display: none;" class="sub-menu">
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
</li>
<li>Item 2</li>
....
</ul>
</div>
$(".my-menu ul li.has-children").on('mouseenter', function () {
$(this).children('.sub-menu').show();
});
$(".sub-menu").on('mouseleave', function () {
$(this).fadeOut();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="my-menu">
<ul>
<li class="has-children">
Item 1
<ul class="sub-menu">
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
</li>
<li>Item 2</li>
....
</ul>
</div>

Display parent UL and for the root parent both UL and LI node

<ul id="ul_Book1">
<li id="li_Book1"> Book1 </li>
<ul id="ul_Chap1">
<li id= "li_Chap1"> Chapter 1</li>
<ul>
<li id="li_Sect11" > Section 1.1 </li>
<li id="li_Sect12" > Section 1.2 </li>
<li id="li_Sect13" > Section 1.3 </li>
</ul>
</ul>
<ul id="ul_Chap2">
<LI id= "li_Chap2"> Chapter 2</LI>
<ul>
<li id="li_Sect21" > Section 2.1 </li>
<li id="li_Sect22" > Section 2.2 </li>
<li id="li_Sect23" > Section 2.3 </li>
</ul>
</ul>
<ul id="ul_Chap3">
<li id= "li_Chap3"> Chapter 3</li>
<ul>
<li id="li_Sect31" > Section 3.1 </li>
<li id="li_Sect32" > Section 3.2 </li>
<li id="li_Sect33" > Section 3.3 </li>
</ul>
</ul>
function menuDisplayPath(li_id) {
var idVal = li_id;
var $obj = $('li').filter(function () { return $(this).attr('id') == idVal; }).parents();
$($obj.get().reverse()).each(function () {
if ($(this).is("li")) {
$(this).find('li').each(function () {
$(this).show();
});
$(this).find('Ul').each(function () {
$(this).show();
});
}
});
}
When a LI node is selected , say "Section 3.2" , I would like to expand/show only "Book1-- Chapter3 -- Section 3.2" and rest of the UL nodes under Book1 should not expand.
But my function menuDisplayPath(li_id) is expanding all the UL under Book1 and also display all LI's. What am I missing in the function.
Assuming all is expanded on load.
First, I corrected many missing double-quotes and extra spaces...
So here is your HTML:
<input type="reset" id="reset" value="Expand all">
<ul id="ul_Book1">
<li id="li_Book1"> Book1 </li>
<ul id="ul_Chap1">
<li id="li_Chap1"> Chapter 1</li>
<ul>
<li id="li_Sect11"> Section 1.1 </li>
<li id="li_Sect12"> Section 1.2 </li>
<li id="li_Sect13"> Section 1.3 </li>
</ul>
</ul>
<ul id="ul_Chap2">
<li id="li_Chap2"> Chapter 2</li>
<ul>
<li id="li_Sect21"> Section 2.1 </li>
<li id="li_Sect22"> Section 2.2 </li>
<li id="li_Sect23"> Section 2.3 </li>
</ul>
</ul>
<ul id="ul_Chap3">
<li id="li_Chap3"> Chapter 3</li>
<ul>
<li id="li_Sect31"> Section 3.1 </li>
<li id="li_Sect32"> Section 3.2 </li>
<li id="li_Sect33"> Section 3.3 </li>
</ul>
</ul>
</ul>
And here is the way to hide the other chapters on click of a li with a section id:
$(document).ready(function(){
$("#ul_Book1").on("click","ul ul li", function(){
$(this).parent().parent().siblings("ul").each(function(){
$(this).hide(); // Hides all other chapter
});
});
$("#reset").on("click",function(){
$("#ul_Book1").children("ul").each(function(){
$(this).show();
});
});
});
Fiddle
Now... Can't tell you how to display the <section> since I didn't see the relevant HTML.
The following worked for me:
function open($li) {
$('.content').hide();
$li.children().show();
if ($li.hasClass('section')) $li.parent().parent().children().show();
}
// test driver
$(document).ready(function() {
$('li').click(function (e) { open($(this)); e.stopPropagation(); });
});
.content {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="book">
<li class="chapter">Chapter One
<ul class="chapter content">
<li class="section">Section One<br><i class="content">1.1 contents</i></li>
<li class="section">Section Two<br><i class="content">1.2 contents</i></li>
</ul>
</li>
<li class="chapter">Chapter Two
<ul class="chapter content">
<li class="section">Section One<br><i class="content">2.1 contents</i></li>
<li class="section">Section Two<br><i class="content">2.2 contents</i></li>
</ul>
</li>
</ul>
Basically you put the section element you want to be open inside the open($li) function.
You should also only put <li> elements inside <ul> elements.
I hope this is what you wanted.

Dynamic element doesn't respond on call

I have a menu and when I click a button to add a item to another item( to be a submenu) the item/parent doesn't respond to the jQuery code for the parent items.
$('.menu li.has-sub>a').on('click', function() {
alert("Working");
});
$(".test").click(function(event) {
event.preventDefault();
$(this).after("<ul></ul>");
$(this).parent().addClass("has-sub");
$(this).parent().find("ul").append("<li><a href='#'>SubItem</a></li>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
<ul>
<li>Item
</li>
<li class="has-sub">Item
<ul>
<li>SubItem
</li>
</ul>
</li>
</ul>
</div>
Use
$("body").on('click',".test",function(event) {})
try:
$(".test").on('click',function(event) {})
$('.menu li.has-sub>a').on('click', function() {
alert("Working");
});
$(".test").on('click',function(event) {
event.preventDefault();
if($(this).parent().find("ul").length == 0) {
$(this).after("<ul></ul>");
$(this).parent().addClass("has-sub");
}
$(this).parent().find("ul").append("<li><a href='#'>SubItem</a></li>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
<ul>
<li>Item
</li>
<li class="has-sub">Item
<ul>
<li>SubItem
</li>
</ul>
</li>
</ul>
</div>

removing html tags but keep the inner html

I have a nav menu which have a mega menu.It has several markup to make it a mega menu.But i want to remove some of the markups when in small viewport.
So my markups are
<ul class="megamenu-wrapper">
<li>
<ul>
<li>Home</li>
<li>Abort</li>
<li>Contact</li>
</ul>
</li>
<li>
<ul>
<li>gang</li>
<li>menu</li>
<li>food</li>
</ul>
</li>
</ul>
what i want
<ul class="megamenu-wrapper">
<li>Home</li>
<li>Abort</li>
<li>Contact</li>
<li>gang</li>
<li>menu</li>
<li>food</li>
</ul>
i have two mega-menu-wrapper
What i have tried
var megaContents = $('.megamenu-wrapper li ul').contents();
$('.megamenu-wrapper li ul').replaceWith( megaContents );
It makes a same list in two each mega menu and in each megamenu there is about 5 times repetation of each elements.
Anyone please help.
Use
//Fimd child ul li and append it to main ul
$('.megamenu-wrapper > li > ul > li').appendTo('.megamenu-wrapper');
//Remove li having ul
$('.megamenu-wrapper > li:has(ul)').remove();;
$(document).ready(function() {
$('.megamenu-wrapper > li > ul > li').appendTo('.megamenu-wrapper'); +
$('.megamenu-wrapper > li:has(ul)').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="megamenu-wrapper">
<li>
<ul>
<li>Home
</li>
<li>Abort
</li>
<li>Contact
</li>
</ul>
</li>
<li>
<ul>
<li>gang
</li>
<li>menu
</li>
<li>food
</li>
</ul>
</li>
</ul>
use .each() if you have multiple menus
$('.megamenu-wrapper') each(function () {
$(this).find('> li > ul > li').appendTo(this);
$(this).find(' > li:has(ul)').remove();
});
DEMO
With your current markup, you can use append() which will take the children li with anchors and append them as direct children of .megamenu-wrapper
Then, use remove() to remove the former parent li elements which now contain empty ul children
$('.megamenu-wrapper').append($('li:has(a)'));
$('.megamenu-wrapper').children('li:has(ul)').remove();
Update
For multiple menus, you can use the snippet above, but wrap it in an each() call
$('.megamenu-wrapper').each(function(){
$(this).append($(this).find('li:has(a)'));
$(this).children('li:has(ul)').remove();
});
$('.megamenu-wrapper').each(function(){
$(this).append($(this).find('li:has(a)'));
$(this).children('li:has(ul)').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="megamenu-wrapper">
<li>
<ul>
<li>Home</li>
<li>Abort</li>
<li>Contact</li>
</ul>
</li>
<li>
<ul>
<li>gang</li>
<li>menu</li>
<li>food</li>
</ul>
</li>
</ul>
<ul class="megamenu-wrapper">
<li>
<ul>
<li>Home</li>
<li>Abort</li>
<li>Contact</li>
</ul>
</li>
<li>
<ul>
<li>gang</li>
<li>menu</li>
<li>food</li>
</ul>
</li>
</ul>

nested list css problems

I am having trouble nesting a list in the following. The nested list isn't appearing on the page. I assume its something to do with my JS hiding it. Can anyone see what the problem may be - it's driving me mad!
<ul class="question">
<li>QUESTION goes here
<ul>
<li>ANSWER goes here>
</li>
</ul>
</li>
<li>QUESTION 2 goes here
<ul>
<li><a href="#">ANSWER 2 goes here>
<li>
<ul>
<li>nested list item 1</li>
<li>nested list item 2</li>
<li>nested list item 3</li>
</ul>
</li></a>
</li>
</ul>
</li>
</ul>
My JS:
<script>
$(document).ready(function () {
$('#question > li > a').click(function(){
if (!$(this).hasClass('active')){
$('#question li ul').slideUp();
$(this).next().slideToggle();
$('#question li a').removeClass('active');
$(this).addClass('active');
}
else{
$('#question li ul').slideUp();
$('#question li a').removeClass('active');
}
});
});
</script>
Here:
http://jsfiddle.net/eAJjs/
$('#question > li > a').click(function () {
if (!$(this).hasClass('active')) {
$('#question>li>ul').slideUp();
$(this).next().slideToggle();
$('#question>li>a').removeClass('active');
$(this).addClass('active');
} else {
$('#question>li>ul').slideUp();
$('#question>li>a').removeClass('active');
}
});
<ul id="question">
<li>QUESTION goes here
<ul>
<li>ANSWER goes here>
</li>
</ul>
</li>
<li>QUESTION 2 goes here
<ul>
<li><a href="#">ANSWER 2 goes here>
<li>
<ul>
<li>nested list item 1</li>
<li>nested list item 2</li>
<li>nested list item 3</li>
</ul>
</li></a>
</li>
</ul>
</li>
</ul>

Categories

Resources