關於querySelectorAll的一個坑


剛學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,是靜態的,不隨文檔的更新而變化。

真是愉快貼心的設計(┬_┬)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM