Reputation: 982
I'm not sure my current implementation is available all the time:
function isNodeList(nodes) {
var result = Object.prototype.toString.call(nodes);
// modern browser such as IE9 / firefox / chrome etc.
if (result === '[object HTMLCollection]' || result === '[object NodeList]') {
return true;
}
//ie 6/7/8
if (typeof(nodes) != 'object') {
return false;
}
// detect length and item
if (!('length' in nodes) || !('item' in nodes)) {
return false;
}
// use the trick NodeList(index),all browsers support
try {
if (nodes(0) === null || (nodes(0) && nodes(0).tagName)) return true;
}
catch (e) {
return false;
}
return false;
}
A common situation is {length:1,item:function(){return [];}}
The value of result in chrome / safari / opera is '[object NodeList]'.
In firefox and IE 9 , it is '[object HTMLCollection]'.
Which is the standard value?
Upvotes: 36
Views: 35031
Reputation: 1154
Below is a JavaScript function to check if an HTMLCollection or NodeList exists in the DOM of a web page, and the code below was tested in the Chrome Dev Tools > Console tab of https://stackexchange.com/:
function ifElemExists(elem) {
if((elem instanceof NodeList) || (elem instanceof HTMLCollection)) return true;
return false;
}
const elem1 = document.querySelector('.blah');
const elem2 = document.querySelectorAll('.siteHeader');
const elem3 = document.getElementById('footer');
const elem4 = document.getElementsByClassName('blah');
console.log(ifElemExists(elem1)); // Output: false
console.log(ifElemExists(elem2)); // Output: true
console.log(ifElemExists(elem3)); // Output: false
console.log(ifElemExists(elem4)); // Output: true
Upvotes: 0
Reputation: 900
The following should return true, if nodes is of type NodeList
NodeList.prototype.isPrototypeOf(nodes)
@DavidSpector, for HTMLCollection you can similarly use :
HTMLCollection.prototype.isPrototypeOf(collection)
Upvotes: 53
Reputation: 12452
I created a benchmark of all answers here to see, what is the best approve in speed. Turns out NodeList.prototype.isPrototypeOf(nodes)
is by far the fastest. But in a normal use-case nodes instanceof NodeList
would be fine too.
I personally would just not pick the isNodeList
function, because its slow, custom and too much overhead.
Upvotes: 1
Reputation: 606
Check if variable is an HTMLcollection or a dom element
var foo = document.getElementById('mydiv');
var foo2 = document.getElementsByClassName('divCollection');
console.log(foo instanceof HTMLElement);
console.log(foo instanceof HTMLCollection);
Upvotes: 12
Reputation: 2502
Here is how to test if an object is a NodeList in modern browsers:
if (nodes instanceof NodeList) {
// It's a NodeList object
}
Upvotes: 17
Reputation: 338326
I would structure the code differently:
function isNodeList(nodes) {
var stringRepr = Object.prototype.toString.call(nodes);
return typeof nodes === 'object' &&
/^\[object (HTMLCollection|NodeList|Object)\]$/.test(stringRepr) &&
(typeof nodes.length === 'number') &&
(nodes.length === 0 || (typeof nodes[0] === "object" && nodes[0].nodeType > 0));
}
Notes:
"item"
is not mandatorily in a nodeListhasOwnProperty()
instead of in
nodeType
instead of tagName
, as text nodes or comments do not have a name&&
chain if you see fitUpvotes: 25
Reputation: 1028
script:
Element.prototype.isNodeList = function() {return false;}
NodeList.prototype.isNodeList = HTMLCollection.prototype.isNodeList = function(){return true;}
use like this:
var d; // HTMLCollection|NodeList|Element
if(d.isNodeList()){
/*
it is HTMLCollection or NodeList
write your code here
*/
}else{
/*
it is not HTMLCollection and NodeList
write your code here
*/
}
Upvotes: 13
Reputation: 289
This answer is probably really really late, but....
if (nodes == '[object NodeList]') {
// It's a nodeList
}
Upvotes: 6