美文网首页
关于querySelectorAll的一个坑

关于querySelectorAll的一个坑

作者: oopsist | 来源:发表于2017-05-16 09:39 被阅读42次

    刚学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,是静态的,不随文档的更新而变化。

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

    相关文章

      网友评论

          本文标题:关于querySelectorAll的一个坑

          本文链接:https://www.haomeiwen.com/subject/skgkxxtx.html