深入理解javascript中的動態集合——NodeList、HTMLCollection和NamedNodeMap

來源:互聯網
上載者:User

標籤:枚舉   注意事項   turn   app   cto   for   元素   sel   attr   

NodeList

  NodeList執行個體對象是一個類數組對象,它的成員是節點對象,包括childNodes和querySelectorAll()方法傳回值

<div id="test"></div><script>console.log(test.childNodes);//[]//IE7-瀏覽器並未定義NodeList對象,會報錯,其他瀏覽器返回trueconsole.log(test.childNodes instanceof NodeList)</script>
<div id="test"></div><script>console.log(document.querySelectorAll(‘div‘));//[div#test]//IE8-瀏覽器不支援querySelectorAll()方法,返回false,其他瀏覽器返回trueconsole.log(document.querySelectorAll(‘div‘) instanceof NodeList)</script>

  動態集合是指DOM結構的變化能夠自動反映到所儲存的對象中

<div id="test"></div><script>var childN = test.childNodes;console.log(childN);//[]test.appendChild(document.createElement(‘div‘));console.log(childN);//[div]</script>

靜態

  [注意]NodeList並不都是動態集合,其中querySelectorAll()傳回值就是靜態集合NodeStaticList

<div id="test"></div><script>var seles = test.querySelectorAll(‘div‘);console.log(seles);//[]test.appendChild(document.createElement(‘div‘));console.log(seles);//[]console.log(test.querySelectorAll(‘div‘));//[div]</script>

數組

  由於NodeList是類數組對象,並不是真正的數組對象,可以使用slice()方法將其變成真正的數組

<div id="test"></div><script>var childN = test.childNodes;console.log(childN instanceof Array);//falsevar childNew = Array.prototype.slice.call(childN);console.log(childNew instanceof Array);//true</script>

  但是,由於IE8-瀏覽器將NodeList實現為一個COM對象,不能使用Array.prototype.slice()方法,必須手動枚舉所有成員

<div id="test"></div><script>var childN = test.childNodes;console.log(childN instanceof Array);//falsefunction convertToArray(nodes){    var array = null;    try{        array = Array.prototype.slice.call(nodes)    }catch(ex){        array = [];        var len = nodes.length;        for(var i = 0; i < len; i++){            array.push(nodes[i]);        }    }    return array;}var childNew = convertToArray(childN);console.log(childNew instanceof Array);//true</script>

 

HTMLCollection

  HTMLCollection對象與NodeList對象類似,也是節點的集合,返回一個類數組對象。但二者有不同之處

  NodeList集合主要是Node節點的集合,而HTMLCollection集合主要是Element元素節點的集合。Node節點共有12種,Element元素節點只是其中一種。關於12種節點類型的詳細資料移步至此

  HTMLCollection集合包括getElementsByTagName()、getElementsByClassName()、getElementsByName()等方法的傳回值,以及children、document.links、document.forms等元素集合

<div id="test"></div><script>var childN = test.children;//IE7-瀏覽器並未定義HTMLCollection對象,會報錯,其他瀏覽器返回trueconsole.log(childN instanceof HTMLCollection);var tags =test.getElementsByTagName(‘div‘);//IE7-瀏覽器並未定義HTMLCollection對象,會報錯,其他瀏覽器返回trueconsole.log(tags instanceof HTMLCollection);</script>    

動態

  與NodeList對象不同,所有的HTMLCollection對象都是動態

<div id="test"></div><script>var childN = test.children;var tags =test.getElementsByTagName(‘div‘);console.log(childN,tags);//[]、[]test.innerHTML = ‘<div></div>‘;console.log(childN,tags);//[div]、[div]</script>    

  [注意]與NodeList對象類似,要想變成真正的數組Array對象,需要使用slice()方法,在IE8-瀏覽器中,則必須手動枚舉所有成員

 

NamedNodeMap

  可能一些人沒有聽過NamedNodeMap對象,該對象的常見執行個體對象是attributes屬性

<div id="test"></div><script>var attrs = test.attributes;console.log(attrs instanceof NamedNodeMap);//true</script>

動態

  該對象也是一個動態集合

<div id="test"></div><script>var attrs = test.attributes;console.log(attrs);//NamedNodeMap {0: id, length: 1}test.setAttribute(‘title‘,‘123‘);console.log(attrs);//NamedNodeMap {0: id, 1: title, length: 2}</script>

 

注意事項

  動態集合是個很實用的概念,但在使用迴圈時一定要千萬小心。可能會因為忽略集合的動態性,造成死迴圈

var divs = document.getElementsByTagName("div");for(var i = 0 ; i < divs.length; i++){    document.body.appendChild(document.createElement("div"));}

  在上面代碼中,由於divs是一個HTMLElement集合,divs.length會隨著appendChild()方法,而一直增加,於是變成一個死迴圈

  為了避免此情況,一般地,可以寫為下面形式

var divs = document.getElementsByTagName("div");for(var i = 0,len = divs.length; i < len; i++){    document.body.appendChild(document.createElement("div"));}

   一般地,要盡量減少訪問NodeList、HTMLCollection、NamedNodeMap的次數。因為每次訪問它們,都會運行一次基於文檔的查詢。所以,可以考慮將它們的值緩衝起來

 

最後

  NodeList是節點的集合,HTMLCollection是元素節點的集合,NamedNodeMap是特性節點的集合,它們都是類數組對象

  對了,還有一個更經典的類數組對象——函數內部的arguments,它也具有動態性

PS:原文https://www.cnblogs.com/xiaohuochai/p/5827389.html

深入理解javascript中的動態集合——NodeList、HTMLCollection和NamedNodeMap

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.