Search code examples
jqueryjquery-selectorssizzle

Decoupling Sizzle.js from jQuery, and replacing it with Sel.js


I recently came across Sel.js which, among other things, supports the Draft CSS Level 4 Selectors (such as the Subject selector which lets you target the parent of a matched CSS node).

I would love to start playing with this library in combination with jQuery, and am curious if anyone has experience (or a good guess for how to accomplish) replacing the Sizzle.js selector library which jQuery is based on with a different selector library (in this case Sel.js).

Any ideas, or examples to look at on the web someplace for decoupling jQuery from Sizzle, and making it instead rely on a different selector engine?


Solution

  • This isn't necessarily a true replacement, per-se, but rather a fall-back. Sizzle will throw an error when encountering what it considers to be "invalid syntax", such as the CSS4 Subject Selector (div! > .jquery-css4, as an example).

    > Uncaught Error: Syntax error, unrecognized expression: div! > .jquery-css4

    One solution is to catch {} those errors thrown by Sizzle, then attempt to fall back to Sel.js for selection instead, by overwriting the $() function as follows:

    $ = function (selector, context) {
        try {
            return jQuery(selector, context);
        } catch (e) {
            return jQuery(sel.sel(selector, context));
        }
    };
    

    After overriding this way, you can then use:

    $('div! > .jquery-css4');
    

    ...which will correctly return the <div> which contains a child of class .jquery-css4.

    As an alternative, you could create a simple css4 selection plugin, using something like:

    $.css4 = function(selector, context) { 
        return $(sel.sel(selector, context));
    };
    

    At which point the above could be re-written:

    $.css4('div! > .jquery-css4');
    

    The benefit of this approach is that it does not rely on error-handling, and is more declarative. In essence - you should know when you're using a CSS4 selector, and need the added support, and when you aren't. However - both approaches are fairly non-intrusive.

    For anyone using these methods, though, please note: I have not tested extensively with queries using the context parameter. It may not play nice with Sel.js - so if you need to take it to that further step, please be aware that you may need to enhance this code further.

    Here is a working jsFiddle showing the code in-action.