Search code examples
javascriptdomcss-selectorsselectors-api

Identity selector for element.querySelector?


I'm writing an application where I am storing relative references to elements as a CSS selector suitable for passing into querySelector. When I want to store a relative reference to the "base" element, I would like to have a selector that will return that same element.

What is the identity selector for the querySelector method of an Element as defined in the Level 1 Selectors API that satisfies the following?

var identitySelector = "<this is the selector I want to know>"

for (int i = 0; i < document.all.length; i++) {
    var elem = document.all[i];
    if (elem !== elem.querySelector(identitySelector)) {
        throw identitySelector + " is not the identity selector";
    }
}

Update:

As this selector isn't available, I'm going to wrap my call to querySelector with a function that returns the context element if the selector is equal to the pseudo-class :root.

var identitySelector = ":root"

var querySelectorProxy = function(elem, selector) {
    return selector === ':root' ? elem: elem.querySelector(identitySelector);
}

for (int i = 0; i < document.all.length; i++) {
    var elem = document.all[i];
    if (elem !== querySelectorProxy(elem, selector)) {
        throw identitySelector + " is not the identity selector";
    }
}

Solution

  • There isn't one.


    John Resig provided a link to a discussion in his blog topic Thoughts on querySelectorAll.

    His beef is that while you can search from any element node, the selector you pass takes in to consideration the entire document. (Personally, I think this is the right approach.) Because of this, he was hoping there would be an identity selector like you're describing.

    jQuery (Sizzle) uses a bit of a hack by using the ID of an element (or assigning a temporary one if not available) and reconstructing the selector to prepend that ID selector.

    Something like this:

    var identitySelector = "<this is the selector I want to know>"
    
    for (int i = 0; i < document.all.length; i++) {
        var elem = document.all[i],
            needs_id = false;
        if( !elem.id ) {
            needs_id = true;
            elem.id = '___some___obscure___value___';
        }
        if (elem !== elem.querySelector( '#' + elem.id )) {
            throw identitySelector + " is not the identity selector";
        }
        if( needs_id ) {
            elem.id = null;
        }
    }
    

    ...though I don't know what this would accomplish here.