How is the jQuery selector $('#foo a') evaluated? How is the jQuery selector $('#foo a') evaluated? jquery jquery

How is the jQuery selector $('#foo a') evaluated?


That is correct - Sizzle (jQuery's selector engine) behaves the same way as CSS selectors. CSS and Sizzle selectors are evaluated right-to-left, and so #foo a will find all a nodes, then filter those by nodes that descend from #foo.

You improve this by ensuring that your leaf selectors have a high specificity, usually by giving them a class or ID.


how should we do that in a better way?

Use the context parameter from jQuery.

$('a', '#foo');

Now jQuery will search all anchors within the context of the element with id: foo.

In your query the context is defaulted to document when omitted:

$('#foo a'); == $('#foo a', document); 

In this case, your query is indeed not efficient.

You might take a look at this article.


While it is true that Sizzle is a right-to-left engine (which is the same way css is interpreted), it is not true that the specific selector in your example would select all anchor elements on the page and then filter their parents to match the id of "foo". Sizzle actually optimizes any selector that starts with an ID and uses that as the context for the entire selection, rather than using the document. In other words, the selector you've chosen basically translates to:

document.getElementById("foo").getElementsByTagName("a")

Really, that's not a bad selector at all.

However, given the other things jQuery needs to do (which includes looping over the elements to merge them onto the jQuery instance), jQuery("#foo").find("a") will always be the fastest because jQuery implements a jQuery object creation shortcut for id-only selectors, and then it does the find rooted from #foo.

In other words, Sizzle itself is not much different when doing Sizzle("#foo a") and Sizzle("a", document.getElementById("foo")), but jQuery("#foo").find... will be faster because of jQuery's own ID shortcut.

By the way, my remarks on Sizzle is assuming querySelectorAll is not being used. If it is, Sizzle just passes it on to qsa, which still isn't as fast as using jQuery's ID shortcut.