一篇文章介紹這兩者的分別,並且說明如何把節點集合轉換為節點陣列。DOM 有很多內建的 method 送回節點集合,所以釐清這兩個概念非常重要。
節點集合的官方名稱是 NodeList,根據 W3C 的 DOM level 3 核心文件,送回 NodeList 的 methods 包括 Document.getElementByTagName()、Node.childNodes 等,歷遍 NodeList 的方法跟歷遍陣列差不多:
1
2
3
4
| for(var i=0; i<collection.length; i++)
{
//whatever
}
|
但你不能使用陣列專用的 methods 包括 push()、splice()、reverse() 等來處理 NodeList。
有需要的話,你可以用以下的方法把 NodeList 轉換成陣列,這真的十分簡單:
1
2
3
4
5
6
7
8
9
| function collectionToArray(collection)
{
var ary = [];
for(var i=0, len = collection.length; i < len; i++)
{
ary.push(collection[i]);
}
return ary;
}
|
以上代碼可以在任何瀏覽器上執行,調用的時候只需輸入要轉換的 NodeList:
1
| var elements = collectionToArray(document.getElementsByTagName('*'));
|
若果你的瀏覽器支援原生物件原型(native object prototyping),例如 Opera、Firefox、Safari 3,你可以為 NodeList 加入一個 toArray() method:
1
2
3
4
5
6
7
8
9
| NodeList.prototype.toArray = function()
{
var ary = [];
for(var i=0, len = this.length; i < len; i++)
{
ary.push(this[i]);
}
return ary;
};
|
這樣便可以把它當作 NodeList 的內建 mothod 直接調用。
不論你如何進行轉換,它都有一個顯而易見的缺點,就是得到的結果不再是一個 NodeList,即是說:
- 轉換後的陣列喪失了繼承自 NodeList 的屬性和 method,其實 NodeList 只有一個屬性(就是 length,陣列也有這個屬性),和一個 method(就是 item(),不過它通常是多餘的,因為我們可以使用方括號表達法),所以這方面的損失很有限。
- 這不再是一個「活」的集合,實作上 NodeList 是物件參考的集合,如果集合改變(例如成員元素的增加或刪減),它會自動更新以反映這種變化,相反陣列是一個靜態的結構,只代表集合在某特定時間的快照,所以不會隨著 DOM 的變化而更新。視乎你的具體情況,這些變化可以相當大。