views:

193

answers:

4

Are the following exactly equivalent? Which idiom do you use and why?

$('#form1 .edit-field :input')
$('#form1 .edit-field').find(':input')
$('.edit-field :input', '#form1')
$(':input', '#form1 .edit-field')
+4  A: 

The first two are equivalent when comparing element selection. However, the second form, when used in a command chain with a correspoding end() call, can be used to select further child elements within "#form1 .edit-field", i.e.:

$('#form1 .edit-field').find(':input')
   ...
.end().find(':hidden')...
.end()...

I'm uncertain about the second two forms, actually, I beleive they are not valid. Correct me if I'm wrong, but based on the docs, the correct syntax would look like this:

$('.edit-field :input', $('#form1'))
$(':input', $('#form1 .edit-field'))

Either way, IMHO these are less consise ways of saying the same.

In summary, generally I'd stick to the first form, unless you exploit the advantage of the second to traverse further children, as explained above.

David Hanak
+1 for .end() considerations
Ben Blank
+1 for end() too, and all the originals are valid as provided. but then your corrections happen to be valid also :)
Scott Evernden
A: 

The more I code in jQuery, the less I use selectors and the more I traverse instead. I would do:

$('#form1').find('.edit-field').find(':input')

It's longer, but conveys the selection process better with a bit more meaning for each step. Traversing is more favorable for chaining, and it makes end() useful.

qpingu
That's not really traversing, per se.
J-P
+8  A: 

I would use either #2 or #4:

$('#form1 .edit-field').find(':input')
$(':input', '#form1 .edit-field')

Both of the above are essentially the same. Behind the curtain when you specify a context this is what's happening anyway:

jQuery( context ).find( selector );

The reason I would avoid #1 and #3 is because they're both significantly slower than #2/#4.


EDIT: Just did a quick test: 1000 input elements using YOUR selectors:

$('#form1 .edit-field :input')            // 55ms
$('#form1 .edit-field').find(':input')    // 21ms
$('.edit-field :input', '#form1')         // 47ms
$(':input', '#form1 .edit-field')         // 18ms
J-P
It's a bit strange that the first form is so slow, but once browsers support querySelector/querySelectorAll it may become more efficient.
VirtualBlackFox
Interesting; I never would have looked for such a significant performance difference. Good find.
Ben Blank
Strange, but good to know. I wonder then, how would $('#form1').find('.edit-field').find(':input') perform. If your measurements are valid, I would expect this form to be even better...
David Hanak
these are some interesting benchmarks. thanks for the time and effort on this. i have been recently been using deeper context for selectors and this indicates that tends to run faster
Scott Evernden
What browser are these benchmarks from? Just tried FF3 and #2, #3 and #4 perform the same. #1 is slowest by about 25% more.
Crescent Fresh
They're from FF3 ... I know that they may not be accurate - but if you think about it #2 and #4 should be the fastest because jQuery doesn't have to do so much string splitting... (and whatever else it does behind the scene)
J-P
A: 

I would use different forms based on what I already have and what elements I also need to work with. For example, if I need to work with other fields in the same form, I'll save a reference to the $('#form1') to save searching for it multiple times.

ironfroggy