KevBot KevBot - 4 months ago 10
Javascript Question

Is it reliable to only check if an argument is a node before using querySelectorAll on it?

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?

Answer

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 DOM3)
  • 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.