Daniel
Daniel

Reputation: 3

How to exclude a class when using the :first-child and :last-child selectors in jQuery

I have a jQuery problem that I can't seem to work out on my own - while I know how to style the the first and last elements of an unordered using the :first-child and :last-child selectors, I'd like to include a caption inside the UL as well…

I need to put the caption before or after the LI elements inside the UL, but this makes jQuery apply :first-child or :last-child to the P element depending on where it sits in relation to the list of LI elements.

Basically, I'd like to find out how to make :first-child and :last-child selector exclude the P element altogether. Having looked around, I've been able to work out that .not() is probably what I need, but haven't been able to get it to work.

For example, this does not work -

$('ul.grid li:first-child').not($(.caption)).addClass('narrow');

I'd be very grateful if anybody would be able to help me out based on the below

jQuery( document ).ready( function ($) {
    $('ul.grid li:first-child').addClass('narrow');
    $('ul.grid li:last-child').addClass( 'narrow' );
});

HTML:

<ul class="grid">
    <p class="caption">Caption text</p>
    <li>
        <img src="images/test1.jpg" alt="1" />
    </li>
    <li>
        <img src="images/test2.jpg" alt="2" />
    </li>
    <li>
        <img src="images/test2.jpg" alt="2" />
    </li>
</ul>   

Upvotes: 0

Views: 373

Answers (3)

tjm
tjm

Reputation: 7550

Ok, I think I understand. Does this work?

$(function() {
    var ul = $('ul.grid');
    ul.find('li:first').addClass('narrow');
    ul.find('li:last').addClass('narrow');
});

Upvotes: 1

user113716
user113716

Reputation: 322492

First, it isn't valid to have a <p> as a child of a <ul>.

"Basically, I'd like to find out how to make :first-child and :last-child selector exclude the P element altogether."

Aside from removing the <p> temporarily, you can't change the fact that the <p> is the first-child, and not the <li>.

If the <p> is the only concern, you could do this:

$('ul.grid > p:first-child + li').addClass( 'narrow' );
$('ul.grid > li:last-child').addClass( 'narrow' );

This uses the next-adjacent-selector[docs] to select the <li> element that has a p:first-child as its previous sibling.


Since you have multiple ul.grid elements, you could loop them, and then successfully use the first()[docs] method and the last()[docs] method.

$('ul.grid').each(function() {
    $(this).children('li').first().addClass( 'narrow' );
    $(this).children('li').last().addClass( 'narrow' );
});

Upvotes: 3

Mutt
Mutt

Reputation: 935

Instead of trying to target the first and last li elements using selectors, use jQuery's .first() and .last() functions.

jQuery( document ).ready( function ($) {
    $('ul.grid li').first().addClass('narrow');
    $('ul.grid li').last().addClass( 'narrow' );
});

Upvotes: 0

Related Questions