0

Currently, I see that the method querySelectorAll is found on the document which is a node and not an element, and found on HTML elements.

I am working with a function that accepts as the first parameter, either a node, element, or a selector that then finds an element. I need to check type of node, because the function should work is document is passed in.

function queryElement(elementOrSelector) {
    if (!isNode(elementOrSelector)) {
        elementOrSelector = document.querySelector(elementOrSelector);
    }
    // This next line is the line I worry about
    var possibleElements = elementOrSelector.querySelector('[test]');
    ...
}

function isNode(o) {
    return (
        typeof Node === "object" ? o instanceof Node :
        o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string"
    );
}

This allows me to pass in the following:

queryElement(document);
// or
queryElement(document.querySelector('select'));

and they will all work. But right now, I am only checking to see if they are of type node when technically, the querySelectorAll method only exists on the document, and the HTML Element prototype. I believe that Element inherits from Node so that is why most of it is working. But if I only ever check type of node, will I run into problems? Is there a particular node that is also not an Element that will not have querySelectorAll available to it?

KevBot
  • 17,900
  • 5
  • 50
  • 68
  • 4
    you could do `if (!'querySelector' in elementOrSelector)` - this is called "feature detection" – Jaromanda X Jul 22 '16 at 03:56
  • `typeof Node` should return `"function"`, not `"object"`. Are you testing some IE oddity? – Oriol Jul 22 '16 at 04:01
  • @JaromandaX, that is an awesome suggestion, wishing I had thought that one through sooner. – KevBot Jul 22 '16 at 04:04
  • @Oriol, based on some of the oddities talked about in the [accepted answer in this question](http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object), I went with that solution for detecting if type of node. – KevBot Jul 22 '16 at 04:05
  • @KevBot That answer complains about `Node` being a function "instead of the expected object". That makes no sense in ES5. I'm sure the code does not behave like the answerer expected, and even if it did, it's not a reliable check. The reason is probably that the answer is so old that precedes ES5, and maybe some old IE returned "object". – Oriol Jul 22 '16 at 04:09
  • @Oriol, that's great information. I'm reading through a couple of different sources on the Node type/instance now. That point has saved me from a couple pitfalls already. – KevBot Jul 22 '16 at 04:16

1 Answers1

1

Is there a particular node that is also not an Element that will not have querySelectorAll available to it?

Yes. For example:

  • Attribute nodes (removed in DOM4)
  • Doctypes
  • Text nodes
  • Comment nodes

I think the only reliable way to check if something is a node is attempting to use it as a node, and see if it throws an error.

However, checking if the object has a querySelector property (and maybe that its value is a function) is probably enough.

Oriol
  • 274,082
  • 63
  • 437
  • 513