Shaun Inman wrote a quick post on what he’s calling “CSS Qualified Selectors“. The syntax that he’s proposing looks something like this:
a < img[/js] Which says "Find me all <b>a</b> elements that have an <b>img</b> element inside of them." To those of you who are familiar with jQuery we've had a similar selector, <a href="http://docs.jquery.com/Selectors/has#selector">:has()</a>, for quite some time: [js]$("a:has(img)")
If you’re totally bent on Shaun’s syntax (don’t care for :has, I would assume) here’s the two-line plugin that’ll give it to you in jQuery:
jQuery.parse.push(/^\s*(<)(\s*)(.*)$/); jQuery.expr["<"] = jQuery.expr[":"].has;[/js] Then the following will work as you would expect it to: [js]$("a < img")[/js] It's really nice having an extensible selector engine at your disposal.
Greg Wolejko (May 5, 2008 at 4:18 pm)
Wow, this is an awesome stuff.
More in a sense of how jQuery is extensible than changing selector engine, but still this one totally amazed me :)
Alan Hogan (May 5, 2008 at 4:19 pm)
That’s pretty slick.
Bramus! (May 5, 2008 at 4:20 pm)
Really great work!
Iraê (May 5, 2008 at 4:22 pm)
Awesome!
Aditya Mukherjee (May 5, 2008 at 4:33 pm)
jQuery.parse/expr look interesting, but documentation on them is missing. Could we have some so that more can be done with them?
Steve Streza (May 5, 2008 at 4:40 pm)
Very impressive. I had no idea the jQuery selector engine was that mutable.
Lim Chee Aun (May 5, 2008 at 8:05 pm)
Can I do
$("a:has(:not(img))")
, which says “Find me all a elements that DON’T have an img element inside of them.”?John Resig (May 5, 2008 at 8:30 pm)
@Lim Chee Aun: Yes, but just the other way around:
$("a:not(:has(img))")
.f1vlad (May 5, 2008 at 11:34 pm)
Can’t stop being surprised by jquery, loving it. Thanks John!
Tzury Bar Yochay (May 6, 2008 at 1:58 am)
jQuery is a great piece of software by all means.
serkanyersen (May 6, 2008 at 2:07 am)
I wish I had chosen jQuery at the beginning, instead of Prototype. I’m so jealous right now…
Dave (May 6, 2008 at 3:45 am)
That’s great. Can you break down each part so those of us without ninja JavaScript skills can understand it? Thanks
gGus (May 6, 2008 at 8:58 am)
It’s not that hard.. once I changed it to allow a “equal” rule to match all the text inside a tag.
jQuery.extend(jQuery.expr[":"], {
equals: "(a.textContent||a.innerText||jQuery(a).text()||'')==m[3]",
});
I was not able to find another way! It does mean that it’s hard for me to rule jQuery, but not that hard to alter the code :)
czert (May 6, 2008 at 9:04 am)
Is there really need for just another syntactical construct? The xpath syntax for the same thing would be simply “
a[img]
“…John Resig (May 6, 2008 at 9:43 am)
@czert: That conflicts with normal CSS syntax, where
a[img]
looks for the img attribute of the a element.Colin Devroe (May 6, 2008 at 1:13 pm)
Excellent stuff as always Mr. John.
bill weaver (May 6, 2008 at 2:44 pm)
That’s great, John–and I second the motion for more documentation.
Rakesh (May 7, 2008 at 1:24 am)
Is it possible to introduce an OR operator in some ways for anything we search in DOM?
Like:
$(“input[type=’checkbox’|’radio’]”) – which means fetch me all `input` elements which is of type either checkbox or radio.
If not, how can we make it work for all other searches using jquery?
Any help would be appreciated.
BTW, thanks for your support & the great work John. Keep it up.
John Resig (May 7, 2008 at 9:47 am)
@Rakesh: Right now you can do the following with jQuery to achieve an “OR”:
$("input").filter("[type=checkbox], [type=radio]")
czert (May 7, 2008 at 2:08 pm)
Yeah, I see what’s the problem with
a[img]
. Still, it seems to me that using a subset of xpath instead of a custom extension of css selectors might be a more logical way to go…I’m sure this has been discussed already; could anyone point me to a related thread, or briefly sum up the reasons to give up on xpath?
Josue (May 8, 2008 at 1:24 am)
John, how about implementing Shaun’s method into jQuery Selectors in v1.2.4?
Rakesh (May 8, 2008 at 1:24 am)
Thanks John. That works.
One thought, why not we’ve operators like (&&, ||)(?) when filtering/querying the selectors.
William Ukoh (May 8, 2008 at 5:26 am)
Whatever happened to $(“a img”) and $(“a > img”) selectors? I’m sure that does pretty much the same thing
czert (May 8, 2008 at 6:30 am)
@william: nope, more like
$("a > img").parent()
^love *encounter ~flow (May 8, 2008 at 6:49 am)
john, do you have a commented source of your selector parser? i’d like to re-implement some of the stuff in Python, but i have a hard time understanding your javascript. mind to post a little write-up on how you run things within jQuery? cheers, ~flow
Mariusz Nowak (May 12, 2008 at 7:40 am)
I was fan of this idea a while ago.. but now I favor other idea which was proposed on CSS mailing list not so long ago – it’s indication which simple selector elements we want query to return:
e.g.
document.querySelectorAll("!p a")
will return all p elements that has anchor descendant.
Additionaly introduction of ‘scope’ pseudo class would resolve all other issues. e.g.
el.querySelector("!* + :scope")
returns previous element sibling element of el
I think it’s cleaner more powerfull and it doesn’t introduce new combinators (what for?).
Matt (May 15, 2008 at 8:00 am)
I looked at some recent Prototype development a little bit ago, unless I’m mistaken, it appears they are going to support XPath selecting of DOM elements. That would pretty much allow the same thing:
/a[./img]