views:

134

answers:

3

i am having a ul li list

<ul>
<li>Parent
    <ul>
       <li>
          child1
       </li>
       <li>
          child2  
       </li>

    </ul>
</li>
</ul>

and i am trying to use a selector jQuery('ul li:first') and jQuery('ul li:first-child') both giving the same result this makes me confused about the difference between the two is there a example which clarifies the difference between two selectors

+5  A: 

From Official Docs:

The :first pseudo-class is equivalent to :eq(0). It could also be written as :lt(1). While this matches only a single element, :first-child can match more than one: One for each parent.

While :first matches only a single element, the :first-child selector can match more than one: one for each parent. This is equivalent to :nth-child(1).

http://api.jquery.com/first-selector/

Update:

Here is an example using :first-child:

http://jsbin.com/olugu

You can view its soruce and edit yourself. If you replace :first-child with :first, it will only highlight the first word there. This is what is defined for them.

And here is example using :first:

http://jsbin.com/olugu/2

Sarfraz
thanks sarfraj, can you please modify my example where first-child will yield a result different from :first. sorry for not properly following what you mentioned
sushil bharwani
@sushil bharwani: See my updated answer please.
Sarfraz
thanks a lot.. got the point clear
sushil bharwani
@sushil bharwani: You are welcome :)
Sarfraz
+4  A: 

Sometimes, but not always, the result is (and should) be the same.

Given your HTML:

jQuery('ul li:first').length; // Returns 1

jQuery('ul li:first-child').length; // Returns 2

So, you can see, that the first line is returning only the first li element.

The second line is returning both li elements that are a first-child of their parent.

:first returns the first in a matched set.

:first-child returns elements that are the first child element of their parent.

The first li element in your HTML is also a first child, although using :first-child is yielding more results when you test the length property.

You could actually combine the two selectors if you only want the first match that is a first child.

jQuery('ul li:first-child:first').length; // Returns one
patrick dw
http://www.jsfiddle.net/gDQQL/1 -- an example of which elements are matched
gnarf
@gnarf - Thanks for posting the example. :)
patrick dw
thanks for your explanation. Its very clear now
sushil bharwani
@gnarf - Thanks for introducing me to jsfiddle
sushil bharwani
+1  A: 

From your example:

$('ul li'); // Returns all 3 li's
// <li> Parent ... </li>
// <li> child1 </li>
// <li> child2 </li>

$('ul li:first'); // Returns the first li of all matching li's from above
// <li> Parent ... </li>

Assuming we have all three results from the first selector $("ul li"), then the :first-child will filter out any element from that list that is not the first child of it's parent. In this case, <li> child2 </li> gets filtered out because it was the 2nd child of a <ul>.

$('ul li:first-child')​;​ // Returns all li's that are the first child of any ul
// <li> Parent .. </li>
// <li> child1 </li>

Also, for the first-child selector, the element has to be the very first child in the DOM, and not in the jQuery result set. For example, with the given structure:

<div>
    <h1>First</h1>
    <span>Second</span>
    <span>Third</span>
</div>

the query below will yield 0 results as <span> is not the first-child of div.

$("div span:first-child")

A good way to understand first-child would be to think of it as a filter that will filter out any element in the current result set, if it is not the very first child of its parent.

Anurag
+1 for a wonderful explanation; specially the div span example this makes the concept very clear thanks a lot for taking time for it
sushil bharwani
You're most welcome. Glad it was helpful :)
Anurag