I'm designing a JavaScript selector engine, and I'm currently focused on parsing the selector string. Specifically, combinators.
The CSS3 combinators I know of are:
>
(children)space
(descendants)+
(next sibling)~
(all next siblings)
Which is fine for how CSS works (how style rules are applied). However, I'm now realizing (now that I'm examining this paradigm more closely) that this seems a bit limiting in a JavaScript setting.
Below I've created an alternative list of combinators. What I would like to know is:
- Do any of the current selector engines stray from standard CSS selection methods? (I'm familiar with Sizzle and Sly, but none of the others)
- Do you see any reason why any of the combinators I've listed wouldn't work well?
- Do you think having more selector string options (more combinators, more filters, etc) is beneficial or are just a waste/confusing/dumb/etc?
Thanks all in advance for your thoughts!
>
(children)>>
(descendants) (also, space would still work)+
(next sibling)++
(all next siblings) (also, tilde would still work)-
(previous sibling)--
(all previous siblings)*
(previous and next siblings)**
(all siblings)^
(parent)
Example 1: div ^ span
- get all spans with a div child
Example 2: div ** span
- get all span siblings of div
Example 3: .lastListItem -- li
- all li previous to the li with class .lastListItem
Example 4: #thing ^ div ** .error
- all items with class .error
that are siblings of #thing's parent (assuming #thing's parent is a div)
p.s. Oh, and I also thought of having a placeholder character that could stand in for any simple selector. So, Example 4 might look like this (with an underscore as a placeholder):
Example 4 alt: #thing ^ _ ** .error
- all items with class ".error" that are siblings of #thing's parent (no matter what kind of element #thing's parent is)
4 Answers 4
YES! Its a terrible idea. Sizzle uses CSS syntax and rocks because of it. Why make something off your own standard, use the standards out there. Who is going to use it if its non standard? The HTML 5 craze is here and be on it to get the most user base.
Take sizzle that is the core of jQuery selector engine. Take that and add to it. You may learn something too from John Resig in terms of shortcuts and parsing techniques. That guy is a legend. I studied his code and became way wiser besides looking through all of Douglass Crockford videos.
-
Obviously, supporting the standards is a good thing, which my proposed combinator set does while adding additional functionality. Given that my engine would remain standards compliant, would you still see no value in additional features?encoder– encoder2011年12月15日 06:21:54 +00:00Commented Dec 15, 2011 at 6:21
-
"Stray" means "to deviate from the direct course, leave the proper place, or go beyond the proper limits, especially without a fixed course or purpose". So yes, its a bad idea to "Stray". However if you are enhancing things that is a different story. That is what jQuery did in fact. Using prototype to enhance functionality ONLY if it is not already implemented is a good start.Joonha– Joonha2011年12月19日 01:04:11 +00:00Commented Dec 19, 2011 at 1:04
-
Is Sizzle still effectively at the core of jQuery? Every browser down to IE8 has a native querySelectorAll method.Erik Reppen– Erik Reppen2012年12月20日 05:06:47 +00:00Commented Dec 20, 2012 at 5:06
-
jQuery still supports IE 7 :) Besides, qsa is buggy on IE8.Florian Margaine– Florian Margaine2012年12月20日 07:19:15 +00:00Commented Dec 20, 2012 at 7:19
Instead of making things up, I would possibly look into implementing features from CSS Selectors 4 Spec
And use the !
to mark the subject of a selector
So instead of div ^ span
to select spans with a div child you could use span! > div
EDIT: sorry, spec changed, it's not a $
prepended , it's a !
appended
-
Looking ahead is a good idea - I didn't realize a fourth spec was even in the works. Thx.encoder– encoder2011年12月15日 06:18:58 +00:00Commented Dec 15, 2011 at 6:18
Advantages of CSS selectors:
Everybody knows them already. They serve 99.95% of use-case scenarios and xpath selectors fill in where they don't.
They're perfectly performant in most supported browsers nowadays. Even IE8 has a native querySelectorAll method (but still no getElementsByClassName method oddly enough). querySelectorAll actually uses the CSS engine in most cases so perf can be a little surprising, but it's still going to be tricky to beat a native method with string examination followed by logic.
It's okay to reinvent the wheel. I encourage such behavior and !@#$ anybody who says otherwise. Unless I'm paying you and it's not Friday, but that Friday thing and paying you is pure fantasy on my part.
But if you're asking me if I'm going to use your selector engine enhancements, I'm probably not. Between knowing the core DOM API, jQuery and now querySelectorAll, I haven't run into an element or elements I couldn't grab without a brief one-liner in a very long time. Most of your examples are suggesting a need for code that relies overly much on patterns of HTML structure which to me is a recipe for brittle code that's difficult to read or simply requires one more method call in the core stuff or jQuery which is a lot less effort and more legible than trying to remember selectors that aren't actually CSS or X-Path.
Before you go too far into implementing your custom selector engine, I would suggest you check to see wether you aren't just reimplementing XPath. It is an alternate XML selector engine that is implemented by most browsers
"#thing ^ _ ∗∗ .error"
When your syntax starts looking like a regular expression, you're doing it wrong. I can getall items with class ".error" that are siblings of #thing's parent
quite easily, why would I use your library? Sometimes less is not more...