Skip to content

@DavidBruant /gist:1016007

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
(document.querySelectorAll('*')).forEach ?
var els = document.querySelectorAll('a');
els.forEach(function(e){console.log(e.href);}); // TypeError: els.forEach is not a function
// Why?
// document.querySelectorAll returns a NodeList.
// First thing first, as opposed to other NodeList, this one is not live, mostly because the
// implementation of a live object would be terribly complicated for some selectors
// NodeList are a DOM interface introduced in DOM core level 1 (random guess)
// The ECMAScript binding ( defines
// NodeList as objects. Unfortunately, the spec is not very accurate in how this object should be
// implemented. It does not say if things are inherited or not, no word on NodeList.prototype
// The de-facto standard is apparently that the protoype chain looks roughly like:
// myNodeList -> NodeList.prototype -> Object.prototype
// As you can notice, Array.prototype is not here. It has to be noted that at the time NodeList were
// invented + standardized was before/at the time of ECMAScript 3.
// At this time, Array.prototype only had:
// .concat, .join, .pop, .push, .reverse, .shift, .slice, .sort, .splice, .unshift
// Most of these methods are not applicable to NodeList since they either write on the NodeList.
// .forEach, .filter, etc. came later on with ECMAScript 5 but it was too late to consider adding
// Array.prototype on the prototype chain (is it really too late?)
// A workaround: on FF4 and Chrome, I have been able to have the following running:
<!DOCTYPE html>
<html lang="en">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
html, body {
td {
<script type="text/javascript">
NodeList.prototype.forEach = Array.prototype.forEach;
HTMLCollection.prototype.forEach = Array.prototype.forEach; // Because of
function randomColorString(){
var r, g, b;
r = Math.floor(256*Math.random()).toString(10);
g = Math.floor(256*Math.random()).toString(10);
b = Math.floor(256*Math.random()).toString(10);
return ('rgb('+ r +','+ g +','+ b +')');
function createTable(row, col){
var t = document.createElement('table');
var r,c;
var i,j;
for(i=0 ; i<row; i++){
r = document.createElement('tr');
for(j=0; j<col ; j++){
c = document.createElement('td');
return t;
function windowLoad(){
var table = createTable(6, 10);
var cells = document.getElementsByTagName('td');
cells.forEach(function(e,i,a){ = randomColorString();
window.addEventListener("load", windowLoad, false);
<title> TITLE </title>
// THE END !
// ... wait a minute
// Apparently, this doesn't work with document.querySelectorAll on FF4. I'll have to dig into that.
// THE END (until progress is made in the direction of DOM ECMAScript binding?)

Ha, this is brilliant in its simplicity! Thank you very much! I was just starting to tear my hair because the result from a querySelectorAll() call didn't support forEach.


Actually, now, I would have a completely different advice which is to turn every NodeCollection/HTMLCollection to an actuall array.
Something like:
function $$(selector){
return, 0);


Thanks for the feedback. I'll keep that in mind but currently a forEach method is all I need.



    var querycollection = WinJS.Utilities.query(".className_1", document);
    querycollection.forEach(function (e) {
        // do some stuff with 'e'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.