Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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:

  1. 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)
  2. Do you see any reason why any of the combinators I've listed wouldn't work well?
  3. 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)

share|improve this question
3  
"#thing ^ _ ∗∗ .error" When your syntax starts looking like a regular expression, you're doing it wrong. I can get all items with class ".error" that are siblings of #thing's parent quite easily, why would I use your library? Sometimes less is not more... –  Yannis Rizos Dec 14 '11 at 22:08
    
It should be noted that anyone who cares about performance doesn't use selectors. The optimum solution in most situations is to simply not use selectors. –  Raynos Dec 14 '11 at 23:46
1  
@Raynos Speed alone is not performance. Fast doesn't always mean efficient. The optimal solution is to use selectors when you actually need them, and not harm your development by chasing milliseconds. Only when you've identified a feature as a major bottleneck, should you care of its performance, anything else is premature... –  Yannis Rizos Dec 14 '11 at 23:55
    
@YannisRizos I agree, I just find it rare that I actually need selectors. –  Raynos Dec 15 '11 at 0:17
    
@YannisRizos I agree, that last example is a bit esoteric; so maybe the placeholder is a bad idea (or I could maybe choose a different character for it). However, do you feel the extra combinator options themselves hold no value? ^ is no harder to understand than >, and ~ is no more intuitive than ++. It's just that we already know what > and ~ do - but after a few uses you'd know ^ and ++ just as well... –  encoder Dec 15 '11 at 6:36

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.

share|improve this answer
    
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 Dec 15 '11 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 Dec 19 '11 at 1:04
    
Is Sizzle still effectively at the core of jQuery? Every browser down to IE8 has a native querySelectorAll method. –  Erik Reppen Dec 20 '12 at 5:06
    
jQuery still supports IE 7 :) Besides, qsa is buggy on IE8. –  Florian Margaine Dec 20 '12 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

share|improve this answer
    
Looking ahead is a good idea - I didn't realize a fourth spec was even in the works. Thx. –  encoder Dec 15 '11 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.

share|improve this answer

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.