HTMLCollection 和 Nodelist 的異同?
1. w3 關于這兩者的定義
HTMLCollection: An
HTMLCollectionis a list of nodes. An individual node may be accessed by either ordinal index or the node'snameoridattributes. Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.NodeList: The
NodeListinterface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented.NodeListobjects in the DOM are live.The items in the
NodeListare accessible via an integral index, starting from 0.
HTMLCollection 和 NodeList 都是元素節點的集合, 前者可以按照索引/節點name/節點id 屬性訪問, 后者可以按照索引訪問,
1.1 實體屬性
HTMLCollection 和 NodeList 都只有一個實體屬性:
length: 回傳節點集合的長度
1.2 實體方法
| HTMLCollection | NodeList |
|---|---|
HTMLCollection.item():傳入元素 index 回傳特定的節點 |
NodeList.item():傳入索引回傳特定節點 |
HTMLCollection.namedItem():傳入節點的 name 屬性,回傳特定的節點 |
NodeList.entries():回傳key-value 的迭代器 |
| ??HTMLCollection 沒有 forEach 方法 | NodeList.forEach():節點遍歷方法 |
NodeList.keys():回傳NodeList 的所有key值的迭代器,這里也就是索引 |
|
NodeList.values()回傳NodeList 的所有value值的迭代器,也就四節點本身 |
一些示例:
<body>
<p name="p1" >Lorem, ipsum dolor.</p>
<p name="p2" >Lorem ipsum dolor sit amet.</p>
<p name="p3" >Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</body>
<script>
const paras = document.getElementsByClassName('para');
console.log(paras.item(0).innerHTML);//Lorem, ipsum dolor.
console.log(paras.namedItem('p3').innerHTML);//Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</script>
<body>
<p name="p1" >Lorem, ipsum dolor.</p>
<p name="p2" >Lorem ipsum dolor sit amet.</p>
<p name="p3" >Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</body>
<script>
const paras = document.querySelectorAll('.para');
console.log('log1:', paras.item(0).innerHTML);
console.log('log2:', paras.entries());
console.log('log3:', paras.entries().next());
console.log('log4:', paras.keys());
console.log('log5:', paras.keys().next());
console.log('log6:', paras.values());
console.log('log7:', paras.values().next());
paras.forEach((p) => {
console.log('[p.innerHTML]: ', p.innerHTML);
});
</script>

特別說明,在實體方法中,
NodeList/HTMLCollection.item()方法僅接受索引值,
2. 哪些常見操作會回傳這二者?
HTMLCollection
-
document.getElementsByTagName -
document.getElementsByClassName -
HTMLElement.children -
document.forms -
document.images
NodeList:
document.getElementsByNamedocument.querySelectorAllHTMLElement.childNodes
3. 二者有什么相同點?
二者所包含的結點都是回應式的,也就是說,當所依賴的檔案發生了變化,相應的DOM視圖也會發生更新,
NodeList
為了驗證這一點,我們可以使用 Array.from(淺拷貝來測驗一下):
<script>
const paras = document.querySelectorAll('.para');
const copy = Array.from(paras);
copy.forEach((cp) => {
cp.innerHTML += new Date().toLocaleTimeString();
});
paras.forEach((p) => {
console.log('[p.innerHTML]: ', p.innerHTML);
});
//[p.innerHTML]: Lorem, ipsum dolor.9:42:54 AM
//[p.innerHTML]: Lorem ipsum dolor sit amet.9:42:54 AM
//[p.innerHTML]: Lorem ipsum dolor sit amet, consectetur adipisicing
</script>

說明拷貝物件中的DOM 元素發生了變化,視圖會發生更新,
HTMLCollection
對于 HTMLCollection 也是這樣的,
<script>
const paras = document.getElementsByClassName('para');
const copy = Array.from(paras);
copy.forEach((cp) => {
cp.innerHTML += new Date().toLocaleTimeString();
});
[...paras].forEach((p) => {
console.log('[p.innerHTML]: ', p.innerHTML);
});
//[p.innerHTML]: Lorem, ipsum dolor.9:42:54 AM
//[p.innerHTML]: Lorem ipsum dolor sit amet.9:42:54 AM
//[p.innerHTML]: Lorem ipsum dolor sit amet, consectetur adipisicing elit.9:42:54 AM
</script>
需要注意的是,這里HTMLCollection 類陣列是沒有forEach 方法的, 所有我們用擴展元算符(其實也是淺拷貝)將其轉換成了一個陣列,
4. 二者有什么區別?
最重要的區別是, HTMLCollection 僅包含 tags(以及id/name分別標記的) 元素, 而 NodeList 包含所有的節點, 例如:
-
元素節點
-
屬性節點
-
文本節點(空白字符也會被視作文本節點)
-
注釋節點
node types
示例:
<body>
<ul id="myList">
<!-- List items -->
<li name="li-name-01" id="li-id-01">List item 1</li>
<li name="li-name-02" id="li-id-02">List item 2</li>
<li name="li-name-03" id="li-id-03">List item 3</li>
<li name="li-name-04" id="li-id-04">List item 4</li>
<li name="li-name-05" id="li-id-05">List item 5</li>
</ul>
</body>
<script>
const ul = document.getElementById('myList');
console.log('[ul.children]: ', ul.children);
console.log('[ul.childNodes]: ', ul.childNodes);
</script>

這意味著,對于有id節點的 HTMLCollection 回傳型別, 你可以這樣去訪問:
console.log('[li[0]]: ', li[0]); //li#li-01
console.log("[li['li-01']]: ", li['li-01']);//li#li-01
并且這二者完全一樣:
console.log(li[0] === li['li-01']);//true
name 也是如此
另外,盡管如此,HTMLCollection/NodeList 的 item 方法依舊僅能通過索引訪問,而不能夠通過id/name 訪問,
const li = document.getElementsByTagName('li');
const _li = document.querySelectorAll('li');
//以下列印: li#li-03
console.log('[li.item(2)]: ', li.item(2));
console.log('[_li.item(2)]: ', _li.item(2));
//以下列印: li#li-01
console.log('[li.item("")]: ', li.item(''));
console.log('[li.item("li-03")]: ', li.item('li-03'));
console.log('[_li.item("")]: ', _li.item(''));
console.log('[_li.item("li-03")]: ', _li.item('li-03'));
即item引數如果接收一個非數值引數,將默認回傳第一個元素,如果沒有元素,那么回傳 null!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/544131.html
標籤:Html/Css
上一篇:fetch和ajax的區別,fetch請求攜帶cookie問題
下一篇:幾行代碼給網站添加暗黑模式
