NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;And now we can chain the forEach method after anything that returns a NodeList (or HTMLCollection in IE9) object.
document.getElementsByClassName("links").forEach(function(node){
 console.dir(node)
})
document.querySelectorAll(".menu").forEach(function(node){
 console.dir(node)
})
And many others work as well:
NodeList.prototype.map = HTMLCollection.prototype.map = Array.prototype.map NodeList.prototype.filter = HTMLCollection.prototype.filter = Array.prototype.filterBut there are some methods that do not work the way you may expect:
NodeList.prototype.pop = Array.prototype.pop
var collection = document.querySelectorAll(".example")
console.log( collection.length ) // 13
collection.pop()
console.log( collection.length ) // 13
But there is a way to avoid this problem and similar ones: instead of directly using the Array prototype we explicitly convert it to an array with a simple method.
NodeList.prototype.toArray = function(){
 return Array.prototype.slice.call(this) 
}
document.getElementsByTagName("a").toArray()
Yeah, is not as sexy but it works a lot better and nobody will have to guess if it returns a NodeList or an Array.Just to cheer you up after that disappointment lets implement the find method on arrays, similar to the one jQuery uses.
Array.prototype.find = function(selector){
 var matches = [];
 var each = Array.prototype.forEach;
 each.call(this,function(ele){  
  if(ele.querySelectorAll){
   each.call(ele.querySelectorAll(selector),function(ele){
    if(matches.indexOf(ele) === -1){
     matches.push(ele)
    }
   })
  }
 }) 
 return matches;
}
Now we can do cool stuff, like:
[document].find(".related a").map(function(ele){
 // your awesome code
})
The ECMAscript standard doesn't guarantee that Array.prototype.slice.call works on non-Array objects. In fact, that throws an error in IE.
ReplyDeleteAs i said the the beginning this is aimed for modern browsers, and Array.prototype.slice.call works in EI9. But thanks to you i noticed that i have to use the HTMLCollection prototype instead of NodeList in IE9.
DeleteAwesome. jQuery features with 20x the speed.
ReplyDelete