Hristo
Hristo

Reputation: 46477

having trouble selecting an element's child with jQuery

I have some nested elements as such:

<div id="knownID">
 <div class="knownClass">
   <span>
     <nobr>
       <span class="knownClass2">
         <span> ... </span>       <--- this keeps expanding deeper and deeper
         <span></span>            <--- this is the one I need!!!
       </span>
     </nobr>
   </span>
 </div>
</div>

I'm trying to select this by doing...

$('#knownID span.knownClass2 span:nth-child(2)').html();

... but its not working out. How can I select that 2nd <span> inside the <span> with class="knownClass2"? I've also tried...

$('#knownID > span.knownClass2 span:nth-child(2)').html();

... but it is returning null. I guess I'm not very familiar with how the nth-child() selector works in jQuery. Would someone mind explaining how it works as well as provide a possible solution to my problem?

Thanks, Hristo

Upvotes: 2

Views: 592

Answers (6)

BudgieInWA
BudgieInWA

Reputation: 2255

You need to have a > between knownClass2 and the nth-child thing like this:

$('#knownID  span.knownClass2 > span:nth-child(2)').html();

Upvotes: 0

Pan Thomakos
Pan Thomakos

Reputation: 34350

You might want to try:

$("#knownID span.knownClass2 > span:nth-child(2)").html();

This reads: Find the 2nd child of type span directly under a span whose class is "knownClass2" that is nested somewhere inside an element whose id is "knownId".

The documentation can be found here:

http://api.jquery.com/category/selectors/

PS: Here is a context based solution as well:

$(" > span:eq(1)", "span.knownClass2", "div#knownID").html();

Upvotes: 2

Stephen
Stephen

Reputation: 18964

You could try this:

$('#knownID')
    .children('div.knownClass')
    .children('span')
    .children('nobr')
    .children('span.knownClass2')
    .children('span:first')
    .next()
    .html();

Using explicit functions like this is faster than lumping them all together in a single string, as you've done. This is because jQuery's selector engine works right to left. Using functions like this will zero in on the ID element first, and then walk down to where you want to be.

Why functions are faster
jQuery uses the Sizzle Selector Engine. This engine is amazing, but one thing to note is that it works from right to left in a selector query. What does that mean? Take, for example, this jQuery snippet:

$('#foo a.bar');

Sizzle will first find every anchor on the page that has the class bar, and then check each one to see if it is an ancestor of the element with id foo. This is not optimized, especially if there are many anchor tags on the page. Sizzle must do it this way because it doesn't know explicitly what you are intending to find.

This, however:

$('#foo').children('a.bar');

Will first find the element with id foo, and then step down one level to the anchors with class bar. It's much faster. You can tell jQuery do this, because you have foreknowledge of your DOM structure.

Upvotes: 1

John Hartsock
John Hartsock

Reputation: 86882

Use the :eq() selector which gets the nth item in the jQuery object. The list is zero indexed.

$("div#knownID span.knownclass2 span:eq(1)").html()

Here is a demo http://www.jsfiddle.net/96RyH/1/

Upvotes: 1

Alec Gorge
Alec Gorge

Reputation: 17390

This works fine for me:

$("#knownID .knownClass .knownClass2 span:nth-child(2)")

See the JSBin here: http://jsbin.com/opoji3/edit

Maybe you have an error elsewhere?

Upvotes: 1

jwegner
jwegner

Reputation: 7403

You could do this:

$("span.KnownClass2").children(":last").html();

Upvotes: 0

Related Questions