Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are HTMLCollection and NodeList iterables?

Tags:

In ES6, an iterable is an object that allows for... of, and has a Symbol.iterator key.

Arrays are iterables, as are Sets and Maps. The question is: are HTMLCollection and NodeList iterables? Are they supposed to be?

MDN documentation seems to suggest a NodeList is an iterable.

for...of loops will loop over NodeList objects correctly, in browsers that support for...of (like Firefox 13 and later)

This appears to corroborate Firefox's behaviour.

I tested the following code in both Chrome and Firefox, and was surprised to find that Firefox seem to think they are iterables, but Chrome does not. In addition, Firefox thinks that the iterators returned by HTMLCollection and NodeList are one and the same.

var col = document.getElementsByClassName('test'); // Should get HTMLCollection of 2 elems  var nod = document.querySelectorAll('.test');      // Should get NodeList of 2 elems  var arr = [].slice.call(col);                      // Should get Array of 2 elems    console.log(col[Symbol.iterator]);    // Firefox: iterator function, Chrome: undefined  console.log(nod[Symbol.iterator]);    // Firefox: iterator function, Chrome: undefined  console.log(arr[Symbol.iterator]);    // Firefox & Chrome: iterator function  console.log(col[Symbol.iterator] === nod[Symbol.iterator]);  // Firefox: true  console.log(col[Symbol.iterator] === arr[Symbol.iterator]);  // Firefox: false
<div class="test">1</div>  <div class="test">2</div>

One really weird, confusing thing: running the code snippet produces a different result from copying it and running in an actual file/console in Firefox (particularly last comparison). Any enlightenment on this weird behaviour here would be appreciated too.

like image 747
light Avatar asked Jul 08 '15 04:07

light


2 Answers

Symbol.iterator support for NodeList, HTMLCollection, DOMTokenList, and DOMSettableTokenList was discussed and added to the WHATWG's DOM spec last year.

like image 76
greiner Avatar answered Sep 28 '22 00:09

greiner


Unfortunately, not yet. But until they are, you can easily polyfill them like so:

HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 
like image 24
Jwashton Avatar answered Sep 28 '22 01:09

Jwashton