I have the follow list that I need to be able to hide all accept for what is actually in focus with class active.
<Ul>
<Li>something</li>
<ul>
<li>Something</>
<li>Something</>
</ul>
<Li>something</li>
<Li>something</li>
<Li>
<Ul>
<Li class="active">something</li>
<Li>omething</li>
</Ul>
</li>
<Li>something</li>
</Ul>
I need to be able to use .hide() on all li that are not related to the bottom level one with the active class
The result would be
<Ul>
<Li>something</li>
<Li>something</li>
<Li>something</li>
<Li>
<Ul>
<Li class="active">something</li>
<Li>omething</li>
</Ul>
</li>
<Li>something</li>
</Ul>
You can traverse up the DOM yo find the first level li element and its siblings. If you have only two levels, this should work:
$('li.active').parent().closest('li').siblings().children('ul').hide();
If you have more than two levels, I suggest to give the root ul a class or ID:
$('li.active').closest('#root > li').siblings().children('ul').hide();
$( 'li:not(.active,.active ~ li,.active li,:has(.active))' ).hide();
This selects all li elements, but excludes (by using :not()):
.active — the active li element itself
.active ~ li — sibling li elements of the active li element
.active li — descendant li elements of the active li element
has(.active) — li elements that have the active li element as its descendant
jsfiddle demo
If you want to keep showing descendants of the active li element's siblings as well, add .active ~ li li to the :not() selectors:
$( 'li:not(.active,.active ~ li,.active li,.active ~ li li,:has(.active))' ).hide();
jsfiddle demo
Following up on OP's first comment to this answer:
Just add an li before the initial selector:
$( 'li li:not(.active,.active ~ li,.active li,.active ~ li li,:has(.active))' ).hide();
jsfiddle demo
Related
I have a accordian-style nav here. So every time an H3 is clicked, the list items drop down.
1.I want to color the H3 green if it's clicked, so users know what's currently clicked.
2.I also want to color whatever item/dog is clicked ( the < a > elements).
So the currently clicked Heading and subheading should both be highlighted.
<div id="accordian">
<ul class="sidebar-nav" id=menu>
<li class="active">
<h3>ITEMS</h3>
<ul>
<li> item1</li>
<li> item2</li>
<li> item3</li>
</ul>
</li>
<li>
<h3>dogs</h3>
<ul>
<li> dog1</li>
<li> dog2</li>
<li> dog3</li>
</ul>
</li>
</ul>
</div>
THis is what I tried so far for 1, it doesn't work. Also, not sure how to do 2.
.sidebar-nav li.active{
color:green;
}
$('ul.sidebar-nav li h3').on('click', function(){
$('ul.sidebar-nav li').removeClass('active');
$(this).addClass('active');
});
You can do something like this:
$('ul.sidebar-nav li h3').on('click', function(){
$("ul.sidebar-nav li ul li, ul.sidebar-nav li h3").removeClass("active");
$(this).addClass("active");
});
$('ul.sidebar-nav li ul li').on('click', function(){
if($(this).parents("li").find("h3").hasClass("active")){
$(this).addClass("active");
}
});
.active{
color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="accordian">
<ul class="sidebar-nav" id=menu>
<li>
<h3>ITEMS</h3>
<ul>
<li> item1</li>
<li> item2</li>
<li> item3</li>
</ul>
</li>
<li>
<h3>dogs</h3>
<ul>
<li> dog1</li>
<li> dog2</li>
<li> dog3</li>
</ul>
</li>
</ul>
</div>
The idea is to use the clicked element to find the h3 and li that need to be highlighted. Also, in CSS, make the selector more generic so it will apply to both the h3 and li elements.
You are not targeting the H3 tag with your active class. In your code, $(this) is referring the the li. You will need to target the parent H3 of clicked li that has the listener.
EDIT
In the code example see my comments to the lines I added. I target all h3 tags and remove the active class to clear everything out, then I target just the parent h3 tag of the clicked li.
Also update your style to have a less specific class for any element with class active:
.active {
color:green;
}
$('ul.sidebar-nav li').on('click', function(){
$('ul.sidebar-nav li').removeClass('active');
// removes all active classes on h3 tags
$('#accordian').find('h3').removeClass('active');
$(this).addClass('active');
// add active to parent h3 as well
$(this).parents('h3').addClass('active');
});
// If you want them to to highlight independently you need 2 listeners
$('#accordion').find('.sidebar-nav h3').on('click', function() {
// removes all active classes on h3 tags
$('#accordian').find('h3').removeClass('active');
// add active to parent h3 as well
$(this).addClass('active');
});
$('#accordion').find('.sidebar-nav a').on('click', function() {
$('#accordion').find('.sidebar-nav a').removeClass('active');
$(this).addClass('active');
});
I'm trying to change the 'active' class for the clicked list item but I'm missing something. Here is what my HTML and jquery look like:
HTML
<ul class="additional-menu">
<li class="active"> Link1</li>
<li>Link2</li>
<li>Link3</li>
</ul>
jQuery
$("#link2").click(function(){
if ($(this).find('#additional-menu li').hasClass('active')) {
//console.log("Active class seen");
$(this).find('#additional-menu li').removeClass('active');
$(this).addClass('active');
}
});
Any idea what I'm missing? I'm not even detecting the active class at this point...
You could minimize your code to just
$('.additional-menu').on('click','li', function(){
$(this).addClass('active').siblings().removeClass('active');
});
Demo at http://jsfiddle.net/DvHBp/
There are many problems in the code
//from what i can understand you need to change the active class to the clicked li element not just the link2 element
$("#link2").click(function(){
// additional-menu is not an id it is a class and it is not a descendant of the li element
if ($(this).find('#additional-menu li').hasClass('active')) {
//console.log("Active class seen");
$(this).find('#additional-menu li').removeClass('active');
//if you are using a if statement then addClass should be outside the if block
$(this).addClass('active');
}
});
try
jQuery(function(){
var $lis = $('.additional-menu > li').click(function(){
$lis.removeClass('active');
$(this).addClass('active')
});
})
find() get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
You should use
$(this).parent().siblings('#additional-menu li')
because in your html structure #link2 a tag has no descendant of #additional-menu li
You can make something very generic:
<ul class="additional-menu">
<li class="active"> Link1</li>
<li>Link2</li>
<li>Link3</li>
</ul>
And using this JavaScript:
$(function(){
$('.additional-menu > li').click(function(){
$('.additional-menu > li').removeClass('active');
$(this).addClass('active');
});
});
Try this solution :
HTML:
<ul class="additional-menu">
<li><a id="link1" href="link1"> Link1</a></li>
<li>Link2</li>
<li>Link3</li>
</ul>
CSS:
.active{
background-color : red;
}
jQuery:
//on first time load set the home menu item active
$(".additional-menu a#link1").addClass("active");
//on click remove active class from all li's and add it to the clicked li
$("a").click(function(){
$("a").removeClass("active");
$(this).addClass("active");
});
Demo
I got the following structure: - nested UL
<ul>
<li>Category 1
<ul>
<li> Category 1.1</li>
<li> Category 1.2</li>
<li> Category 1.3</li>
</ul>
</li>
<li> Category 2
<ul>
<li>Category 2.1</li>
<li>Category 2.2</li>
<li>Category 2.3</li>
</ul>
</li>
<li>Category 3
<ul>
<li>Category 3.1</li>
<li>Category 3.2</li>
<li>Category 3.3</li>
</ul>
</li>
I've applied a rule with CSS:
ul{
list-style: none;
padding:0;
margin:0;
}
ul ul{
display:none;
}
which leaves only the MAIN category shown.
What i was trying to do is, whenever a user clicks on the Category 1/2/3, its <ul> will be visible. I've tried this code:
$(document).ready(function() {
$("ul li").click(function() {
$(this + "ul").Slidedown(800);
});
});
well, basically I was trying to select the <ul element that was inside the main <ul>.
How do I do it?
Try this.
$(document).ready(function() {
$("ul li").click(function() {
$(this).find('ul').Slidedown(800);
});
});
Given your selector, click on Category 1.1 will also call the callback, but it won't do anything since it doesn't have any ul tags. Still, it's better to add a class and bind the event only on those.
this is not a string, it's a DOM element.
Instead of $(this + "ul"), you want $('ul', this).
P.S. .Slidedown should be .slideDown.
$(this).find('ul:hidden').slideDown(800);
something like this should work
$(document).ready(function() {
$("ul > li").click(function() {
$(this).find("> ul").Slidedown(800);
});
});
Although, an even more efficient approach(thanks to Ian) would be:
$(document).ready(function() {
$("ul").children('li').click(function() {
$(this).children("ul").Slidedown(800);
});
});
using the '>' operator tells jquery to only look for direct children, if you don't use '>' the code will apply to the li elements inside the nested ul as well. also, read the other answers info about using 'this' properly.
You're concatenating the DOM element with "ul" to a string - that's not a valid selector. Instead, use .find() to apply the ul selector in the context of the current element.
$(document).ready(function() {
$("ul li").click(function() {
$(this).find('ul').Slidedown(800);
});
});
And maybe make the ul li selector a bit more specific to match only the outer list items.
<ul id="nav">
<li>
Home
</li>
<li>
About
<ul>
<li>The product
<ul> // level 2
<li>x3</li>
<li>x4</li>
</ul>
</li>
<li>Meet the team
<ul> // level 2
<li>x1</li>
<li>x2</li>
</ul></li>
</ul>
</li>
</ul>
using jquery i wanted to select ul of level 2
like if i hover on 'The product' then i want to select only ul[level 2] that is next to it not all level 2 ul.
I use jQuery code to select like this
$('#nav li ul li').mouseover(function(){
$(this).children('ul').css('opacity','.5');
});
but this code effect on both level 2 ul i want to select the ul that is inside that <li> which is hover...
Try this using Child combinator selector:
$('#nav > li > ul > li').mouseover(function(){
$(this).children('ul').css('opacity','.5');
});
This means it will only select list items that are direct children of an unordered list. In other words, it only looks one level down the markup structure, no deeper.
Can do with CSS:
jsfiddle demo
#nav > li > ul > li:hover > ul {opacity:.5;}
Need to add an active class to both parent and child element if a user clicks on the child element in a list. My html is as follows:-
<ul class="tabs">
<li class="accordion">Bar
<ul class="sub">
<li>lorem/li>
<li>ipsum</li>
<li>Lorem Ipsum</li>
<li>Dolor Sit Amet</li>
</ul>
</li>
and I'm using the jquery code below to add an active class to both the parent and child element yet I'm having errors:-
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active").find(".sub li").removeClass("active");
$(this).addClass("active").find(".sub li").addClass("active");
});
Then styled my active class in CSS. say example
.active {background:#EFEFEF;}
only the clicked (this) child element should have the active class applied to it and not the whole li child elements. Now together with the child li (say lorem) the parent li (bar) should also be highlighted. Think of it like a tree accordion menu where both the selected child element and it's parent li have the active class with different css styling.
I'm just going to make an assumption here that you only want to add the active class to the list items like so: http://jsfiddle.net/gfkM4/
I hope that's what you were looking for. Cheers.
try this:
$("ul.tabs li").click(function() {
$("ul.tabs li, .sub li").removeClass("active");
$(this).find(".sub li").andSelf().addClass("active");
})
Updated: http://jsfiddle.net/4G7TJ/3/ (per your new requirement that only one child is selected)
$("ul.tabs li").click(function() {
// remove .active from all li descendants
$("ul.tabs li").not(this).removeClass("active");
$(this)
.addClass("active")
.not('.accordion')
.parents("li:first").addClass("active");
return false;
});
The idea behind returning false is to prevent the 'click' event from being propagated to the parent li when a child li is clicked, since that would undo the styling change on the child.
Update: Working demo - http://jsfiddle.net/4G7TJ/1/
// only trigger the click on direct descendants
// (otherwise the kids get the event first and this won't work)
$("ul.tabs > li").click(function() {
// remove .active from all li descendants
$("ul.tabs li").not(this).removeClass("active");
$(this).addClass("active").find(".sub li").addClass("active");
});
Also - <li>lorem/li> isn't closed, meaning that all of your tags are likely mismatched and you can't be sure what the 'current' list-item is (and in which list) when you click.
Here is demo for applying active class on accordion menu option using jQuery.
HTML:
<ul class="tabs">
<li class="accordion">
<a href="#tab1">
Bar
</a>
<ul class="sub">
<li>
lorem
</li>
<li>
ipsum
</li>
<li>
Lorem Ipsum
</li>
<li>
Dolor Sit Amet
</li>
</ul>
</li>
<li class="accordion">
<a href="#tab2">
Foo
</a>
<ul class="sub">
<li>
lorem
</li>
<li>
ipsum
</li>
<li>
Lorem Ipsum
</li>
<li>
Dolor Sit Amet
</li>
</ul>
</li>
</ul>
CSS:
.tabs li{
list-style:none;
}
.tabs li:hover{
background:#88ccf9;
}
.tabs li a{
color:#334499;
}
.tabs{
border:1px solid #3344ff;
background:#dcfcff;
padding:10px;
}
.tabs .accordion .sub{
padding:3px 3px 3px 18px;
display:none;
}
.tabs .active .sub{
display:block;
}
.tabs li.active{
background:#77d9c9;
}
JQuery:
$(function() {
$("ul.tabs li").click(function() {
// remove .active from all li descendants
$("ul.tabs li").not(this).removeClass("active");
//hide all sub menu except current active
$("ul.tabs li").not(this).find(".sub").hide(400);
//apply active class on current selected menu
$(this).addClass("active");
//check if sub menu exists
if($(this).find(".sub").length>0){
//show the selected sub menu
$(this).find(".sub").show(500);
//apply active class on all sub menu options
$(this).find(".sub li").andSelf().addClass("active");
}
});
});
I have done complete bin on http://codebins.com/bin/4ldqpa5