I know this is a really strange title, but I'll do my best to explain the problem below:
I have a page with a layout similar to the following:
.item pre code pre code .item .item pre code
I want to select the code
ite开发者_运维知识库ms (because I want to loop through them with 'each()'
). However, I want to only select the first 'pre/code'
combo in each .item
block.
How can I do this?
At first I had $(".item pre code")
, which selects all of the 'pre/code'
combos. I noticed in the jQuery docs that there's a :first-child
selector. I tried sticking it on the end of the pre
, but that didn't work.
You need to use the nth-child
selector. This chooses the element that matches the argument (a 1-based index) for each of the parent selectors. (:first
only returns the first pre
; nth-child
returns all pre
s that are the first child of their parent:
$('.item pre:nth-child(1) code')
http://jsfiddle.net/syLMD/
NB that this is equivalent to .item pre:first-child code
. As far as I can tell, that works just fine.
OK, with the knowledge that the first pre
may not contain a code
... You can't do this with a simple selector. This needs more complex filtering:
$('.item')
.data('found', false) // ensure that all item nodes have found = false
.find('pre code') // find descendant code nodes
.filter(function(){
if ($.data(this.parentNode.parentNode, 'found')) { // if this item has already been found
return false; // remove the code element from the selection
} else {
$.data(this.parentNode.parentNode, 'found', true) // mark the item as found
return true; // keep the code element in the selection
}
})
.each(function(){ // for each of these code elements
$('#output').append(this.innerHTML); // or something else
})
.end() // back to the un-filtered selection of code elements
.end() // back to the selection of div.item elements
.data('found', false); // mark them as not found, for the next time
See example. Note that this isn't exactly going to have wonderful performance...
精彩评论