Element和Node的區別你造嗎?
1.寫在前面
我們經常使用document.getElementById去獲取DOM中的元素,也會使用childNodes來獲取子節點。那麼Element和Node的區別是什麼?而什麼又是HTMLCollection,HTMLElement,和NodeList呢?
一個簡單的頁面:
<html>
<body>
<h1>China</h1>
<!-- My comment ... -->
<p>China is a popular country with...</p>
<div>
<button>See details</button>
</div>
</body>
</html>
body
裡的直系子元素一共有三個:h
,p
,div
。我們可以用document.body.childNodes
檢視, 結果如下:
問題來了:
- 1.這麼會有這麼多的#text?
- 2.註釋算節點?
在回答上面兩個問題之前,就有必要理解下什麼是Node
了。
2.Node vs Elemet
以下摘自MDN:
A Node is an interface from which a number of DOM types inherit, and allows these various types to be treated (or tested) similarly.
The following interfaces all inherit from Node its methods and properties: Document, Element, CharacterData (which Text, Comment, and CDATASection inherit), ProcessingInstruction, DocumentFragment, DocumentType, Notation, Entity, EntityReference.
簡單的說就是Node
是一個基類,DOM中的Element
,Text
和Comment
都繼承於它。
換句話說,Element
Text
和Comment
是三種特殊的Node
,它們分別叫做ELEMENT_NODE
, TEXT_NODE
和COMMENT_NODE
。
所以我們平時使用的html上的元素,即Element,是型別為ELEMENT_NODE
的Node
。
利用nodeType
可以檢視所有型別,如下圖:
到這裡,我想我們就可以解釋上面兩個問題了。
實際上Node
表示的是DOM樹的結構,在html中,節點與節點之間是可以插入文字的,這個插入的空隙就是TEXT_NODE
,即:
<body>
we can put text here 1...
<h1>China</h1>
we can put text here 2...
<!-- My comment ... -->
we can put text here 3...
<p>China is a popular country with...</p>
we can put text here 4...
<div>
<button>See details</button>
</div>
we can put text here 5 ...
</body>
這下就順理成章了,body的直系元素(3)+ COMMENT_NODE(1) + TEXT_NODE(5) = 9
3.NodeList vs HTMLCollection
我們用childNodes
找到了NodeList
,但我們操作DOM時往往不想操作Node
(我只想操作元素Element),那麼如何獲取ElementList呢?
其實我們經常使用的getElementsByXXX
返回的就是一個ElementList,只不過它的真實名字是ElementCollection
。
就像NodeList
是Node
的集合一樣,ElementCollection
也是Element
的集合。但需要特別注意的是:
NodeList和ElementCollcetion都不是真正的陣列
如果document.getElementsByTagName('a') instanceof Array
,那麼必然是false
。
4.寫在最後
DOM(Document Object Model)簡稱文件物件模型,它是html和xml是文件程式設計的介面,它將文件解析為樹結構,這個樹的根部就是document
,而document
的第一個子節點(childeNodes[0])就是html,這才有了後面的一系列html元素。
最後附一張DOM圖,此刻再看這張圖是不是覺得回味無窮咧。
參考資料:
2.DOM
3.Node