关于querySelectorAll的一个坑

2017-05-16  本文已影响42人  oopsist

刚学JS的DOM操作时,就知道了匹配一堆元素,会获得NodeList和HTMLCollection这两个对象,不过当时并没有深入去研究两者的区别

因为无论是NodeList还是HTMLCollection,都可以用方括号来获取想要的节点,直到今天

不幸踩坑

今天写了一个网页,用AJAX向后端要数据,格式是JSON,解析后要做一个判断,看看

用来填充数据的HTML DIV元素够不够,不够用,就要调用自定义函数添加一个,直到DIV够用。

这是一个很简单的循环就能完成的事情,我隐约记得书上讲这些集合都是“动态的”

嗯?这意味着我可以这样帅气的写


var data=JSON.parse(xhr.responseText);

var itemArr=document.querySelectorAll('.item');

while(itemArr.length<data.length)

createItem();


一测试,浏览器就卡住了,很明显,这里来了一个死循环

这就意味这itemArr的length属性没有变化~~,没有我想像中的动态增长length

这明显不符合书上写的,很多书

讨论了NodeList和HTMLCollection 并不是文档状态中的一个静态快照

通常是实时,也就是说,你添加一个新的node节点,这两个对象也会变化

那我来测试一下 建立一个简单的html body里面只有一个div class='x'


var test=document.querySelectorAll('.x');

test instanceof NodeList //true

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


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 做到了随文档动态的变化,而NodeList在这里并没有按照动态的规则运行

这很令人费解,因为如果你使用getElementsByName方法返回的也是NodeList对象,但是这个对象的确是动态的

而这里的querySelectorAll返回的NodeList的确不是动态的。

难道问题是出现在了querySelector这个方法上?没错啊,就是querySelectorAll的毛病╮(╯_╰)╭

这个方法返回的NodeList,是静态的,不随文档的更新而变化。

真是愉快贴心的设计(┬_┬)

上一篇下一篇

猜你喜欢

热点阅读