Created
June 9, 2011 03:41
-
-
Save DavidBruant/1016007 to your computer and use it in GitHub Desktop.
(document.querySelectorAll('*')).forEach ?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 (http://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html) 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"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> | |
<style> | |
html, body { | |
margin:0; | |
padding:0; | |
} | |
td { | |
width:100px; | |
height:100px; | |
background-color:purple; | |
} | |
</style> | |
<script type="text/javascript"> | |
NodeList.prototype.forEach = Array.prototype.forEach; | |
HTMLCollection.prototype.forEach = Array.prototype.forEach; // Because of https://bugzilla.mozilla.org/show_bug.cgi?id=14869 | |
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'); | |
r.appendChild(c); | |
} | |
t.appendChild(r); | |
} | |
return t; | |
} | |
function windowLoad(){ | |
var table = createTable(6, 10); | |
document.body.appendChild(table); | |
var cells = document.getElementsByTagName('td'); | |
cells.forEach(function(e,i,a){ | |
e.style.backgroundColor = randomColorString(); | |
}); | |
} | |
window.addEventListener("load", windowLoad, false); | |
</script> | |
<title> TITLE </title> | |
</head> | |
<body> | |
</body> | |
</html> | |
// 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?) |
I have modified and used this:
(function() {
if (typeof NodeList.prototype.forEach === "undefined") {
NodeList.prototype.forEach = Array.prototype.forEach;
}
if (typeof HTMLCollection.prototype.forEach === "undefined") {
HTMLCollection.prototype.forEach = Array.prototype.forEach;
}
})();
thank you!!
Or you could use Array.from(document.querySelectorAll('a'))
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I use
But i'm looking for some library, maybe someone knows more perfect way to fix with library? Does Array.prototype.slice.call() work for every browser?