Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect HTMLCollection/NodeList in JavaScript?

Tags:

javascript

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?

like image 816
simon xu Avatar asked Aug 30 '11 02:08

simon xu


People also ask

Is HTMLCollection a NodeList?

A NodeList and an HTMLcollection is very much the same thing. Both are array-like collections (lists) of nodes (elements) extracted from a document.

What is NodeList in JavaScript?

A NodeList is a collection of document nodes (element nodes, attribute nodes, and text nodes). HTMLCollection items can be accessed by their name, id, or index number. NodeList items can only be accessed by their index number. An HTMLCollection is always a live collection.

What is the difference between NodeList and array?

A NodeList may look like an array, but in reality, they both are two completely different things. A NodeList object is basically a collection of DOM nodes extracted from the HTML document. An array is a special data-type in JavaScript, that can store a collection of arbitrary elements.

What is the difference between node and NodeList?

Node and NodeList are general concepts. A Node is, roughly, a distinct object with some internal state. The name Node implies that the object can be or is a member of some collection, often but not always a list. A NodeList is just a linear list of nodes.


2 Answers

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) 
like image 194
vineethbc Avatar answered Sep 22 '22 23:09

vineethbc


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:

  • less return paths make easier-to-read code
  • stick with one type of logic, if possible (i.e. use less negated checks)
  • "item" is not mandatorily in a nodeList
  • use hasOwnProperty() instead of in
  • use square brackets to index into the list
  • I don't think a try/catch is really necessary, but that might be wrong - you decide
  • check for nodeType instead of tagName, as text nodes or comments do not have a name
  • add more checks to the && chain if you see fit
like image 27
Tomalak Avatar answered Sep 25 '22 23:09

Tomalak