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