【Day20】比较Nodelist与HTML collection的差异

前面提到透过DOM API取得网页节点的方法:

//根据传入的id 名称,找到DOM里面相同id名称的节点。
document.getElementById('idName');

//根据传入的tag名称,回传所有符合条件的NodeList物件。
document.getEleMentsByTagName('tagName');

//根据传入的class名称,回传所有符合条件的NodeList物件。
document.getElementsByClassName('className')

//根据所设定的selector条件(class或id都可以),回传第一个符合条件的节点。
document.querySelector('selector');

//根据所给定的selector条件,回传所有符合条件的 NodeList。
document.querySelectorAll;

由以上方法所回传的可能会有以下三种节点:

  • HTML元素节点(element nodes)
  • 文字节点(text node),包含空白
  • 注解节点(comment node)

getElementById与querySelector都是取得单一元素或节点,没有 index 及 length 属性。

DOM提供2种节点集合,用於容纳多个节点:

  • HTML collection:由「document.getElementsByTagName()」及「document.getElementsByClassName」查询後回传,HTML Collection只收集HTML 元素节点,这个集合不是阵列,不能使用阵列型别所提供的方法,但是有阵列索引(index)及length属性可以使用,是一个有序的动态集合。
  • NodeList:由「document.querySelectorAll()」查询後回传,除了HTML节点外,也包括文字节点、属性节点,这个集合同样不是阵列,不能使用阵列所提供的方法,但是有阵列索引(index)及length属性可以使用。

HTML Collection是一个动态的集合,节点的变动会及时反应在集合中。

<div id="sword">
  <ul id="fiveHero">
    <li id="firstHero">1 东邪</li>
    <li id="secondHero">2 西毒</li>
    <li id="thirdHero">3 南帝</li>
    <li id="fifthHero">4 北丐</li>
    <li id="lastHero">5 中神通</li>
  </ul>
</div>
var outside = document.getElementById('fiveHero');
var collection = document.getElementsByTagName('li');
console.log(collection.length);  //5  得出5个HTML元素节点
console.log(collection[1].textContent);  //"2 西毒"
//清空<ul id="fiveHero">下面的节点
outside.innerHTML = '';
console.log(collection.length);  //0 即时更新为0个元素节点

本来抓取到的HTML collection集合中有5个<li>元素,但是我们用outside.innerHTML =''清空之後,再console.log(collection.length)一次,已经即时更新为0个了。

NodeList大部分都是即时更新的,由childNodes属性返回的NodeList物件是一个动态的集合,但是透过document.querySelectorAll() 及 document.querySelector()取得的NodeList是静态的集合。

<div id="sword">
  <ul id="fiveHero">
    <li id="firstHero">1 东邪</li>
    <li id="secondHero">2 西毒</li>
    <li id="thirdHero">3 南帝</li>
    <li id="fifthHero">4 北丐</li>
    <li id="lastHero">5 中神通</li>
  </ul>
</div>
var outside = document.querySelector('ul');
var list = document.querySelectorAll('li');  //抓取所有<li>元素节点
console.log(list.length);          //5
console.log(list[2].textContent);  //"3 南帝"
//清空<ul id="fiveHero">下面的节点
outside.innerHTML = '';
console.log(list.length);          //5   没有即时更新状态

「outside.innerHTML = ''」清空了底下的<li>元素,但是 console.log(list.length)仍然为5,没有更新为0,所以 document.querySelector() 回传的是一个静态的集合。

But 人生最厉害的就是那个but!由 childNodes 属性返回的 NodeList 物件是一个动态的集合,可以即时更新集合的状态。

<div id="sword">
  <ul id="fiveHero">
    <li id="firstHero">1 东邪</li>
    <li id="secondHero">2 西毒</li>
    <li id="thirdHero">3 南帝</li>
    <li id="fifthHero">4 北丐</li>
    <li id="lastHero">5 中神通</li>
  </ul>
</div>
var outside = document.querySelector('ul');
console.log(outside.childNodes.length);   //5
console.log(outside.childNodes);
// [object NodeList] (11)
//["#text","<li/>","#text","<li/>","#text","<li/>","#text","<li/>","#text","<li/>","#text"]
outside.innerHTML = '';
console.log(outside.childNodes.length);  //0

我们抓取了<ul>,存在变数 outside 里面,利用 coconsole.log() 查询它 childNodes 的长度,然後清空了outside里面的内容,再查询一次childNodes.length,果然即时更新变成0了。

HTML collection 还有一个 nameItem() 方法,可以返回集合中 name 属性和 id 属性值的元素。

<div id="sword">
  <ul id="fiveHero">
    <li id="firstHero">1 东邪</li>
    <li id="secondHero" name="1">2 西毒</li>
    <li id="thirdHero">3 南帝</li>
    <li id="fifthHero">4 北丐</li>
    <li id="lastHero">5 中神通</li>
  </ul>
</div>
var one = document.getElementsByTagName('li').namedItem('firstHero');
var two = document.getElementsByTagName('li').namedItem('2');
console.log(one);     //<li id="firstHero">1 东邪</li>
console.log(two);     //<li id="secondHero" name="2">2 西毒</li>

<<:  Day06 WebRTC 中的 Signaling Server

>>:  树选手3号:XGboost

人脸辨识-day21 资料预处理--2

缺失值处理 在处理大量资料时,资料有些会有缺失的情况,有分以下几种缺失的情况,随机缺失(Missin...

Dungeon Mizarka 025

今天难得有足够的时间可在Dungeon的专案进行调整,本来是想将时间花在整理行为的部份,但一直觉得目...

Android学习笔记11

今天在研究progressBar的时候发现我的xml突然不会跑出提示 所以就开始寻找解决办法 网路上...

iOS APP 开发 OC 第九天,UIWebView & WKWebView

tags: OC 30 day 我们来延续上一篇网路请求原理做出UIWebView吧 把网路请求做成...

後端说修改时只需要送「有修改的栏位」过来

今天来介绍一个,因为後端提出这个需求。要接 PATCH API 而产生的做法。 如果都是 PUT 就...