2

I am trying to learn jquery and have a question -

The div element on the page looks like -

<div id ="1">
    <p id="first"> one 
        <p id="second"> one.one 
            <p id="third"> one.one.one </p>
        </p>
    </p>
</div>

Both the below selectors are giving me the same result -

  $('div p').css({'background-color' : 'blue'}); 

  $('div>p').css({'background-color' : 'blue'});

Shouldn't the second selector just return only the first <p> tag of the <div> element ?

karthikr
  • 97,368
  • 26
  • 197
  • 188
Student
  • 4,481
  • 8
  • 27
  • 32
  • This isn't really jquery question but a css selector question. Here is some more info on them: https://developer.mozilla.org/en-US/docs/CSS/Getting_Started/Selectors – lucuma Apr 15 '13 at 18:44
  • possible duplicate of [CSS '>' selector; what is it?](http://stackoverflow.com/questions/4459821/css-selector-what-is-it) – Mike Mackintosh Apr 15 '13 at 18:44
  • 1
    just a heads up, the "proper" way to do it (from a speed / efficiency standpoint) is `$('div').find('p')`. This will always be faster than the CSS selector method. http://jsperf.com/jquery-find-vs-css-selector2/2 – PlantTheIdea Apr 15 '13 at 18:46
  • `

    ` tags' closing tag is optional. Your code is being parsed as `

    one

    one.one

    ...`. Docs: http://www.w3.org/TR/html-markup/p.html#p-tags
    – gen_Eric Apr 15 '13 at 18:49
  • @LifeInTheGrey I wonder how selecting by tagname compares to selecting by ID?( my guess would be that by ID would be much faster, thus making the jsperf linked somewhat off-topic ) – Kevin B Apr 15 '13 at 18:49
  • @KevinB well the tagname is the child, and it would be moronic to specify a parent when you use an ID to select the child. so ... – PlantTheIdea Apr 15 '13 at 18:50
  • @FelixKling: They are not actually descendants. They are being read as siblings since the closing `` is optional. – gen_Eric Apr 15 '13 at 18:51
  • @LifeInTheGrey: You cannot make this conclusion based on the test you linked to, since the setup and the selector is different. Here is a more appropriate test case: http://jsperf.com/jquery-find-vs-css and it's not surprising that *not* using `.find` is faster. – Felix Kling Apr 15 '13 at 18:51
  • 1
    @Rocket: Right... I was thinking about that `p` elements cannot be nested and that the browser should correct it but I didn't bother testing... will delete my comment and thanks (and +1). – Felix Kling Apr 15 '13 at 18:52
  • @FelixKling good find, i just grabbed the first one i could. – PlantTheIdea Apr 15 '13 at 18:58

5 Answers5

5

$('div p') selects all <p> tags that are descendants of a <div>.

$('div>p') only selects <p> tags that are direct children of a <div>.


What's happening in your code is since the closing </p> tag is optional, the browser is reading your HTML as having 3 <p> (actually 5, since the last 2 closing tags are being "mis-read") tags that are all siblings.

So, it's being read as:

<div id ="1">
    <p id="first"> one</p> 
    <p id="second"> one.one</p>
    <p id="third"> one.one.one</p>
    <p></p>
    <p></p>
</div>

That's why they all became blue. $('div>p') matched them all, since they are all direct children of the <div> (or that's what the browser thinks).

Demo: http://jsfiddle.net/wP7uD/

Open your browser's dev tools and inspect the DOM, you'll see that there are 5 <p> tags.

Moral of this: You cannot have <p> tags as children of <p> tags.


W3C spec for <p> tags: http://www.w3.org/TR/html-markup/p.html

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • 2
    +1 Because everyone else is explaining what `>` does (which the OP seems to understand already) and not why they get that result. – Felix Kling Apr 15 '13 at 19:00
  • 1
    @FelixKling: In the OP's question he says that he expects `$('div>p')` to only return the 1st element. He would be right if it weren't for the fact that `

    ` tags are weird. Also, that's usually how I answer; explain *why* the OP is getting the result he is. :-D

    – gen_Eric Apr 15 '13 at 19:02
2
div p

Match all the p elements which are inside a div, no matter how deep they are inside.

div > p

Match all the p elements which are direct child of a div

What's wrong in your case is the HTML. It's not allowed to have a p nested inside another p; browsers close the first p automatically, before rendering the new one.

Bruno
  • 5,961
  • 6
  • 33
  • 52
2

All the <p> are children of the first <p> element.

Mooseman
  • 18,763
  • 14
  • 70
  • 93
  • Unfortunately, they aren't. ``s are optional, so his code is read as `

    one

    one.one

    ...`. `

    ` tags can't be children of `

    ` tags. http://www.w3.org/TR/html-markup/p.html#p-tags

    – gen_Eric Apr 15 '13 at 18:55
  • @RocketHazmat Invalid? Yes. What the OP cited? Yes. – Mooseman Apr 15 '13 at 19:02
2

div > p implies the first level p child of div. and div p implies p child of div anywhere in the descendant of div

More documentation here

karthikr
  • 97,368
  • 26
  • 197
  • 188
2
Siva Charan
  • 17,940
  • 9
  • 60
  • 95