views:

105

answers:

3

jQuery 1.4:

$('#menu li:last:not(.ignore)').addClass('last');

HTML:

<div id="menu">
    <ul>
        <li>item 1</li>
        <li>item 2</li>
        <li class="ignore">item3</li>
    </ul>
</div>

.. last class is not applied to item 2. What am I doing wrong here?

Thanks

+4  A: 

Change the order of :last and :not():

$('#menu li:not(.ignore):last')
Gumbo
Ah! I'd dismissed that thought because :last:not worked earlier, but not in jquery 1.4 I guess. Thanks anyway!! :)
Nimbuz
@Nimbuz: The selectors `:not(…):last` and `:last:not(…)` have different semantics. The former will first exclude all elements that do not match the `:not(…)` expression and then get the last element of them. The latter will first get the last element and then exclude it if it does not match the `:not(…)` condition.
Gumbo
+2  A: 

The way your expression works is this:

  • Find the element with ID "menu";
  • Find all descendant list items of that element;
  • Limit the results to the very last element in that set;
  • Filter out elements (which is only one element by this point, the last one) that don't have a class of "ignore".

The last element has a class of ignore so it is filtered out. That's why it doesn't work. Reverse the order:

$("#menu li:not(.ignore):last").addClass("last");
cletus
A: 

It seems more logical to me at least to say 'get me the list item before the first occurence of .ignore':

// tested
$("#menu li.ignore:first").prev("li").addClass('last');
karim79