30

How would I select the first <p> element in the following <div> with jQuery?

<div>
    <h1>heading</h1>
    <p>How do I select this element with jQuery?</p>
    <p>Another paragraph</p>
</div>
Web_Designer
  • 72,308
  • 93
  • 206
  • 262

6 Answers6

61

Assuming you have a reference to the div already:

$(yourDiv).find("p").eq(0);

If the first p will always be a direct child of the div, you could use children instead of find.

Some alternatives include:

$(yourDiv).find("p:eq(0)"); //Slower than the `.eq` method
$(yourDiv).find("p:first"); 
$(yourDiv).find("p").first() //Just an alias for `.eq(0)`

Note that the eq method will always be the fastest way to do this. Here's the results of a quick comparison of the eq method, :eq selector and :first selector (I didn't bother with the first method since it's just an alias of eq(0)):

enter image description here

James Allardice
  • 164,175
  • 21
  • 332
  • 312
  • Nice, this looks convincing, Thanks! – Web_Designer Dec 16 '11 at 07:57
  • 1
    No problem, glad I could help :) If you're interested, yet another alternative would be `:lt(1)`. I'm almost certain it will be slower that the `.eq` method too, but it's yet another way of achieving the same thing. – James Allardice Dec 16 '11 at 08:00
  • Wow, that is a significant difference. I don't understand why jQuery would allow :first at all. In the background, it should be converted to :nth-child(1). http://jsperf.com/jq-first-vs-eq/3 Is there a reason this isn't done? – rkw Dec 16 '11 at 08:10
  • @rkw - `:nth-child` does something very different. It returns the element at the specified index (1-based, just for added confusion!) *if it matches the selector*. In your jsperf test, the `:nth-child` example will not match any elements - the first element is an `h2`, not a `p`. I believe that behind the scenes, `:first` is converted to `:eq(0)`, which is shown in my original test. – James Allardice Dec 16 '11 at 08:15
  • @James, ah; thanks. Now I know why people keep on asking about nth-of-type selectors for jquery. – rkw Dec 16 '11 at 08:24
  • @rkw - Yeah, the naming could be slightly misleading, but I don't know what else they could be called really. When people ask for an "nth-of-type" selector, the answer is `:eq(n)`, but the equivalent `.eq(n)` method is faster. – James Allardice Dec 16 '11 at 08:26
  • I really like the eq() solution, it's very readable and will be the one I'll be using from here on. Check out these results though, uses nth-of-type and first-of-type: http://jsperf.com/jq-first-vs-eq/3 – rkw Dec 16 '11 at 08:39
  • @rkw - Nice! Good discovery. I didn't know you could use `:nth-of-type` and the like with jQuery. – James Allardice Dec 16 '11 at 08:46
  • I didn't either till I tried it. It's not in the documentation, so maybe jQuery just passes the selector straight through if it doesn't recognize it? Also, I don't think it's behaving the way I'm expecting it to. Example: on this page, if you type $('div:first-of-type') in the console, you will get over 70 results. I was expecting one. – rkw Dec 16 '11 at 09:04
  • Ah, first-of-type is designed to be used with a parent. It all makes sense now. http://www.w3.org/TR/selectors/#first-of-type-pseudo – rkw Dec 16 '11 at 09:19
  • 3
    @rkw - Probably worth noting that `:first-of-type` and the like will *only work in browsers that support `querySelectorAll`*. Older browsers (in particular IE8 and below) will throw an error, so probably best to stick with `eq`. – James Allardice Dec 16 '11 at 09:44
  • Thanks guys! - intruiging disgussion. :) – Web_Designer Dec 16 '11 at 17:05
5
$('div p:first')

answer was too short to post without this useless sentence.

Edit This is definitely a slow option. After looking at Jame's speed test, it looks like jQuery selectors work best when they piggy back off of css selectors.

rkw
  • 7,287
  • 4
  • 26
  • 39
  • @JamesAllardice That's equal to .First(), because both matches one single element. Whether it's the desired effect depends on Web_Designer's challenge. – Colin Dec 16 '11 at 07:54
  • @Farrell - Yes, it's equal to `.first` and `:first` and `:eq(0)` and `:lt(1)` (there are so many ways of writing the same thing with jQuery), but it should be the fasted of the bunch. – James Allardice Dec 16 '11 at 07:57
  • @rkw - Note that `:nth-child` is not equivalent and won't work in this case. You are right in thinking that selectors work best when they have a CSS equivalent, especially in modern browsers, because the native `querySelector` and `querySelectorAll` methods can be used instead of Sizzle. – James Allardice Dec 16 '11 at 08:19
1

You almost know the answer (from your post title). There is a selector in jQuery called :first-of-type. Use it to find and add class to the first p tag automatically, like so:

$("div p:first-of-type").addClass('someClass');
Devner
  • 6,825
  • 11
  • 63
  • 104
1

$("div p").first();

or $('div p:first');

Reference: http://api.jquery.com/first/

Keep in mind that first() matches only a single element, the :first-child selector can match more than one: one for each parent.

Colin
  • 759
  • 1
  • 5
  • 20
0
$('div p').first()

Should work. I think.

-1

This should work

$( "div p:first-of-type" ).css( "font-size: 10px" );

The above code finds the first paragraph in the div as @Denver pointed and changed its fonts-size to 10px

Here is an example that explains even more about jQuery first-of-type selector

Prabhakar
  • 6,458
  • 2
  • 40
  • 51
  • No, it shouldn't. This answer is, essentially, identical to [the one given by Devner two and a half years ago](http://stackoverflow.com/a/16381687/19068) except you've changed it to select the wrong element. – Quentin Oct 26 '15 at 09:55