Question

I have an <li> that contains another <ul> and <li>.

I want to be able to access either <li> and apply different functionality to each.

I've been going with the approach of:

Example A:

If this <li> contains a <ul>, do this when clicking on the <li>.

Example B:

If this <li> does not contain a <ul>, do this when clicking on the <li>.

It's not working though, so I'm trying to test the basics.

Example A seems to select both <li>'s, even the nested one that does not contain a <ul>.

HTML

<ul>
<li>i do have a ul - i should be green
<ul>
<li>i dont have a ul - i should be red</li>            
</ul>
</li>
<li>i dont have a ul - i should be red</li>
<li>i dont have a ul - i should be red</li>
</ul>

jQuery

// why does this first condition cause both li's to be green?

$("li:has(ul)").css('background','Green');

// uncomment the following and only one is green

//$("li:not(:has(ul))").css('background','Red');

jsFiddle

http://jsfiddle.net/rwone/H5ZdE/2/

Edit:

Just to clarify, I am wanting to be specifically selective so that I can apply different click functionality to each <li>, so that is why I need to figure out how to select them accurately and not just rely on 'overiding' inherited styles etc.

Was it helpful?

Solution 5

Solution:

The following achieves the desired results ie separate functionality for top level and nested <li>'s.

To be honest I don't yet really know how it works, but it works and I added a bit of extra functionality to test things out. But no marks needed for code prettiness.

HTML:

<div id="container">
<ul class="squares">
<li>
<ul class="nested">
<li class="hidden_li" style="height: 20px; width: 50px; background: yellow; display: none; position: relative; z-index: 999999; left: 0px;top: 70px;">
<a href="">test</a>
</li></ul>
</li>
<li>
<ul class="nested">
<li class="hidden_li" style="height: 20px; width: 50px; background: yellow; display: none; position: relative; z-index: 999999; left: 0px;top: 70px;">
<a href="">test</a>
</li></ul>
</li>
<li></li>
<li></li>
// etc
</ul>
</div>

CSS

#container {
height: 205px;
overflow-y: auto;
width: 400px;
}

.select {
border: 2px solid red !important;
}

.select_blue {
border: 2px solid blue !important;
}

.squares {
list-style: none outside none;
margin: 0;
padding: 0;
white-space:nowrap;
}

#container ul li {
background: none repeat scroll 0 0 #FFFFFF;
border: 2px solid #CCCCCC;
border-radius: 4px;
cursor: pointer;
display: inline-block;
height: 100px;
margin-right: 25px;
vertical-align: top;
width: 100px;
}

jQuery

// just for <li>
$(document).on("click","ul.squares > li:nth-child(1n-7)", function (e) {
$(".hidden_li").hide();    
$(this).find(".hidden_li").fadeIn();
$("ul.squares > li:nth-child(1n-7)").removeClass("select");
$(this).addClass("select");
e.preventDefault();
//alert("i am a li");
});

// just for nested <li>
$(document).on("click","ul.nested > li", function (e) {
e.stopPropagation();
$("ul.nested > li").removeClass("select_blue");
$(this).addClass("select_blue");
e.preventDefault();
alert("i am a nested li");
});

More comments and demo on jsFiddle:

http://jsfiddle.net/rwone/H5ZdE/31/

OTHER TIPS

// why does this first condition cause both li's to be green?
$("li:has(ul)").css('background','Green');

The above line does NOT cause both li to be green. It causes the first parent li only to be green. However, because the child li (which does not contain a ul) does not have a background color of its own, it appears to be green because it is inheriting its parent's background color.

The HTML and Javascript you've written conflict. The second <li> is nested inside the first, and because it's styled background green, all child elements are inside that <li> background.

See here: http://jsfiddle.net/H5ZdE/4/

The Javascript is not actually styling that second <li> to background green. It's simply inside the <li> whose background is green.

For selecting an li that has a nested ul use

$('li ul').parent() (this will return the parent li tags of the selected ul tags. You can use li>ul as well)

try this

$("li:has(ul)").css('background', 'green')
$('li ul').css('background', 'red')

http://jsfiddle.net/H5ZdE/6/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top