views:

200

answers:

8

Please help me in this script, what is the problem?

I'd like to addClass "green" to the 5th li.hr in every ul containers in my site. Thanks.

$("ul li.hr").each(function() {
  if ($(this).length = 5) {
    $(this).addClass("green");
  }
});

PS: if its possible with CSS only, tell me how please.

EDIT: the UL got mixed elements, like:

<li class="a">foo</li>
<li class="b">foo</li>
<li class="hr">foo</li>
<li class="c">foo</li>
<li class="a">foo</li>
<li class="hr">foo</li>

... etc. I need the 5th li.hr

A: 

You need the nth-child there:

$("ul li.hr:nth-child(5)").addClass('green');
Sarfraz
tried, but not work :(
neduddki
@marharépa: What happend? What is the error if any?
Sarfraz
No errors, this is my problem too. :(
neduddki
+5  A: 
$('ul').find('li.hr:nth-child(5)').each(function() {
   $(this).addClass("green");
});

Reference: :nth-child selector

CSS3 offers a similar selector, have a read http://www.w3.org/TR/css3-selectors/#nth-child-pseudo

would look like

li.hr:nth-child(5) {
   background-color: green;
}
jAndy
`nth-child` does not behave as expected. Please see my answer.
Josh Stodola
A: 

You can do it this way.

if($("ul li.hr")[4]){
    $($("ul li.hr")[4]).addClass("green");
}
Vagmi Mudumbai
+16  A: 

You can use nth-child of jquery.

$("ul li.hr:nth-child(5)").addClass("green");
Krunal
'ul li.hr:eq(4)' will do the same thing, but in a shorter form.
Ben Rowe
This does not work, because the jQuery implementation of `nth-child` conforms to the [W3C CSS Specification](http://www.w3.org/TR/css3-selectors/#nth-child-pseudo). The selector in your answer only matches an `li` if it is the 5th child of a `ul` *and* has a class of `hr`. I know it seems like nth-child is the answer at first glance, but in this particular scenario, it is not.
Josh Stodola
A: 
var lis = $('ul li.hr');
if(lis.length >= 4) { 
    $(lis[4]).addClass('green'); 
}

Should do the trick. I've tested it in Firebug.

the :nth-child selector doesn't work as you'd expect it, since it doesn't take into account the class selector.

Tudorizer
+2  A: 

li.hr:nth-child(5) will find an .hr that is also the fifth child in its <ul>. If I understand correctly, you're looking for the 5th .hr. Try:

$('ul').find('li.hr:eq(4)').addClass('green');

This isn't a single selector, but should work for your. For every <ul> it finds all .hr elements, and picks the fifth one.

Working example: http://jsfiddle.net/Xv6gX/

Kobi
+9  A: 

Despite the popular consensus, you can't use :nth-child here because it counts all children, regardless of whether or not they match the preceding selector. Only after it grabs the nth element does it compare it to the selector to determine whether it matches. So this: ul li.hr:nth-child(5) actually gets treated as ul li:nth-child(5).hr. This might sound weird, but it strictly conforms to the CSS specification (see the jQuery description).

Luckily, jQuery provides the wonderful :eq() pseudo-class which allows you to filter by a zero-based index, and respects the preceding selector...

$("ul > li.hr:eq(4)").addClass("green");

I even tested this out to make sure it works...

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
  .green { color:green; font-weight:bold; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
  $(function() {
    $("ul > li.hr:eq(4)").addClass("green"); 
  });
</script>
</head>
<body>
  <ul>
    <li class="a">foo</li>
    <li class="b">foo</li>
    <li class="hr">foo</li>
    <li class="c">foo</li>
    <li class="a">foo</li>
    <li class="hr">foo</li>
    <li class="a">foo</li>
    <li class="b">foo</li>
    <li class="hr">foo</li>
    <li class="c">foo</li>
    <li class="a">foo</li>
    <li class="hr">foo</li>
    <li class="a">foo</li>
    <li class="b">foo</li>
    <li class="hr">bar</li> <!-- 5th -->
    <li class="c">foo</li>
    <li class="a">foo</li>
    <li class="hr">foo</li>
  </ul>
</body>
</html>
Josh Stodola
@Josh: Agree with you. It is weird. `nth-child` is not working as expected.
Krunal
Nice answer. Thanks for the example too, I'll use this later, and learn everything about eq. But the point is Borgar's with the pure CSS solution. (my favourite ^^) up for it
neduddki
+2  A: 

You can do this in pure CSS:

/* set rule: select every li.hr element after the 4th  */
ul > li.hr ~ li.hr ~ li.hr ~ li.hr ~ li.hr {
  color: green;
}
/* unset rule: select every li.hr element after the 5th  */
ul > li.hr ~ li.hr ~ li.hr ~ li.hr ~ li.hr ~ li.hr {
  /* reverse the rules set in the previous block here */
  color: black;
}

Caveat: The ~ selector is not supported by IE6. Works fine on everything else.

Borgar
Neet! This is the best solution, because fast, and easy-to-use.
neduddki