Anne van Kesteren

querySelector() and querySelectorAll()

Why do DOM interfaces suck so much? argues that there should be more optional arguments for DOM interfaces. I agree that this is something we could look into making better. (Some time ago I suggested making the last argument of addEventListener optional, as people mess it up.) Feedback on that is welcome on public-webapi@w3.org and is likely also relevant to the WHATWG and W3C HTML WG if it affects interfaces defined by HTML 5. This is not to say that you’ll get an immediate reply and Web browsers will ship with the more convenient method next year, but it has a chance of improving things on the long haul.

APIs we’re introducing now can start right away with sucking less. Well, apart from the names. Thanks to Lachlan Hunt the Selectors API specification has been updated with lots of new examples and the new names. The interfaces are as follows:

interface DocumentSelector {
  Element         querySelector(in DOMString selectors);
  Element         querySelector(in DOMString selectors, in NSResolver nsresolver);
  StaticNodeList  querySelectorAll(in DOMString selectors);
  StaticNodeList  querySelectorAll(in DOMString selectors, in NSResolver nsresolver);
};

interface ElementSelector {
  Element         querySelector(in DOMString selectors);
  Element         querySelector(in DOMString selectors, in NSResolver nsresolver);
  StaticNodeList  querySelectorAll(in DOMString selectors);
  StaticNodeList  querySelectorAll(in DOMString selectors, in NSResolver nsresolver);
};

The versions on Element (ElementSelector) are simply scoped versions of those on Document. Now we need to wait for some implementations.

Comments

  1. That does look like an improvement! I'll be happy to see this kind of interface implemented, although that could take years :) Browser implementation of new Javascript and HTML specs moves at a glacial pace ... hopefully with the increase in firefox and safari use things will get better.

    I also posted about this issue, but in relation to flash embed libraries.

    Posted by Matt at

  2. I hate the new names. The interfaces looks good, though.

    Posted by Asbjørn Ulsberg at

  3. “making the last argument of addEventListener possible” – Possible, or optional?

    Posted by Tomáš Znamenáček at

  4. Anne, you already requested more optional arguments in the DOM. Seems like the Mozilla guys didn't really like it back then.

    There certainly is a lot of improvement to be made: how many times do you want importNode without the deep parameter set to true for example. But, well, addEventListener is a far more urgent case, given the amount of trouble its last argument causes. I'd be happy if the ES bindings for DOM 3 events fix that.

    The newer webapi work seems to be better in this regard. Also, the CSSOM looks quite good.

    Posted by JeroenH at

  5. Tomáš, yeah, thanks. Fixed now.

    Posted by Anne van Kesteren at

  6. Is it possible to implement this on DocumentFragment too, or even on every Node?

    Posted by Sjoerd Visscher at

  7. I hate the new names too. They should use getElement(s)BySelector or getElement(s)ByCSS (i.e. getElement(s)BySomething), which is more consistent with the existing method names.

    Posted by minghong at

  8. They could even just be called getElement() and getElements() for what I care. I just want the names to reflect what the methods actually do (and in some way, what they return) as well as be consistent with the existing DOM methods.

    querySelector() sounds like a void function querying a selector for something mysterious. querySelectorAll() is even less descriptive. "'All'? Oh, you're querying all selectors, I see." Uhm, no. You fail.

    Posted by Asbjørn Ulsberg at

  9. Heh, do note that they are not consistent with the other get* methods as querySelector() and querySelectorAll() return a static list of nodes and not a live one.

    Posted by Anne van Kesteren at

  10. Please do note that at one time in the process, getElement(s)BySelector was chosen, but there were some persons in the working group who plainly refused to use that name. Then I got really disappointed by the whole group and how certain people were able to override certain things without a good reason. And fwiw, I do think returning a static node list for these methods is a mistake. But I'm not going to waste any time on trying to get that changed.

    Posted by Martijn at

  11. The reasons given were that those two methods names are too close to each other if I remember correctly (and I don’t recall them being chosen by the way, nor nominated even; one of them was named different) and that they do not return a live list. You can think that’s a mistake, but that doesn’t mean it’s not a good argument. As for live lists, implementors were not ok with that. Doesn’t make sense to specify something that nobody will implement if the whole goal is to get it implemented.

    Posted by Anne van Kesteren at

  12. I can totally deal with the names. And actually, they're not that bad at all. Plus, it's just as easy to do something like this:

    
    var query = function(q) {
      return querySelectorAll(q);
    };

    But yeah, improving the interfaces will be totally awesome. Thanks for recognizing these things :)

    Posted by Dustin Diaz at

  13. I’ve been wondering what “querySelector” meant since the first time i read it (just ignored it since it sounds boring).

    Now i read that it just means getElementsBySelector() which immediately tells anyone who ever used getElementById or getElementsByTagName what it does.

    Why in the world would you use a puzzling name like querySelector in stead of a self-explanatory name like getElementBySelector?

    And why would you switch from liv nodelists to static ones? I wish we could be more consistent.

    Posted by Jaap at