剛學JS的DOM操作時,就知道了匹配一堆元素,會獲得NodeList和HTMLCollection這兩個對象,不過當時並沒有深入去研究兩者的區別
因為無論是NodeList還是HTMLCollection,都可以用方括號來獲取想要的節點,直到今天
不幸踩坑
今天寫了一個網頁,用AJAX向后端要數據,格式是JSON,解析后要做一個判斷,看看
用來填充數據的HTML DIV元素夠不夠,不夠用,就要調用自定義函數添加一個,直到DIV夠用。
這是一個很簡單的循環就能完成的事情,我隱約記得書上講這些集合都是“動態的”
嗯?這意味着我可以這樣帥氣的寫
1 var data=JSON.parse(xhr.responseText); 2 3 var itemArr=document.querySelectorAll('.item'); 4 5 while(itemArr.length<data.length) 6 7 createItem();
一測試,瀏覽器就卡住了,很明顯,這里來了一個死循環
這就意味這itemArr的length屬性沒有變化~~,沒有我想像中的動態增長length
這明顯不符合書上寫的,很多書
討論了NodeList和HTMLCollection 並不是文檔狀態中的一個靜態快照
通常是實時,也就是說,你添加一個新的node節點,這兩個對象也會變化
那我來測試一下 建立一個簡單的html body里面只有一個div class='x'
1 var test=document.querySelectorAll('.x'); 2 3 test instanceof NodeList //true 4 5 test instanceof HTMLCollection //false
這說明,querySelectorAll返回的是NodeList對象
那來添加一個節點試試看
var node=document.createElement('div'); node.className='x'; document.body.appendChild(node); test.length //還是1!
這說明,文檔結構的改變,並沒有影響到NodeList
既然NodeList沒有任何變化,那我們來試試HTMLCollection對象吧
刷新一下瀏覽器
document.getElementsByClassName返回一個HTMLCollection
1 var test=document.getElementsByClassName('x') 2 3 test instanceof HTMLCollection //true 4 5 var node=document.createElement('div'); 6 7 node.className='x'; 8 9 document.body.appendChild(node); 10 11 test.length //2!!!!!
HTMLCollection 做到了隨文檔動態的變化,而NodeList在這里並沒有按照動態的規則運行
這很令人費解,因為如果你使用getElementsByName方法返回的也是NodeList對象,但是這個對象的確是動態的
而這里的querySelectorAll返回的NodeList的確不是動態的。
難道問題是出現在了querySelector這個方法上?沒錯啊,就是querySelectorAll的毛病╮(╯_╰)╭
這個方法返回的NodeList,是靜態的,不隨文檔的更新而變化。
真是愉快貼心的設計(┬_┬)