Hey Belsnickle,
Good question.
Here’s what the jQuery docs say:
Given a jQuery object that represents a set of DOM elements, the .find() method allows us to search through the descendants of these elements in the DOM tree and construct a new jQuery object from the matching elements. The .find() and .children() methods are similar, except that the latter only travels a single level down the DOM tree.
The way I had always understood this, was that you call find()
on a jQuery object and it will traverse the entirety of that object, looking for what you specified.
Actually answering this question got me interested in what jQuery is doing under the hood at this point.
I had a look through the code of the latest 1.x jQuery version (v1.10.2) and the .find()
method is implemented thus:
find: function( selector ) {
var i,
ret = [],
self = this,
len = self.length;
if ( typeof selector !== "string" ) {
return this.pushStack( jQuery( selector ).filter(function() {
for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( self[ i ], this ) ) {
return true;
}
}
}) );
}
for ( i = 0; i < len; i++ ) {
jQuery.find( selector, self[ i ], ret );
}
// Needed because $( selector, context ) becomes $( context ).find( selector )
ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
ret.selector = this.selector ? this.selector + " " + selector : selector;
return ret;
}
As you can see, the first part of the method is just declaring some variables and the ‘if block’ can be ignored in this case, as we are passing it a string ($slideElement.find("img")
).
In the for block, jQuery is handing things off to the Sizzle selector engine, so I logged the values of the parameters to the console:
console.log(selector, self[ i ], ret);
for ( i = 0; i < len; i++ ) {
jQuery.find( selector, self[ i ], ret );
}
This produced:
img
<li style="float: none; list-style: none; position: absolute; width: 730px; z-index: 50;"> ... </li>
undefined
which at least proves that .find()
is searching the entire object it is passed.
The implementation of .children()
, looks like this:
children: function( elem ) {
return jQuery.sibling( elem.firstChild );
}
Which simply calls the .sibling()
method on the first child of the element it is passed.
The .sibling()
method presumably returns the siblings of any element it is passed (in this case there are none), thus the image we are interested in is returned.
So, it seems that given the fact that .children()
will only deal with first-level children of the jQuery object it is called on whereas .find()
will traverse the whole object, in this case it would indeed more efficient to use .children('img')
.
However …
Just to be sure, I created a test case on jsperf and rather confusingly, this proved the opposite true.
Can you have a look at it. Did I setup something incorrectly?