上節(jié)我們分析了vdom的 Document節(jié)點(diǎn), 這節(jié)我們繼續(xù)閱讀Node和Element恨胚。
1. Node
export function Node () {
`this.nodeId = (nextNodeRef++).toString()
this.ref = this.nodeId
this.children = []
this.pureChildren = []
this.parentNode = null
this.nextSibling = null
this.previousSibling = null
}
Node.prototype.destroy = function () {
const doc = instanceMap[this.docId]
if (doc) {
delete this.docId
delete doc.nodeMap[this.nodeId]
}
this.children.forEach(child => {
child.destroy()
})
}
可以看到node,聲明了nodeid,ref, children, pureChildren, parentNode ,nextSibling(下一兄弟節(jié)點(diǎn)), previousSibling(上一兄弟節(jié)點(diǎn))以及destroy方法拴清。
destroy刪除的原則是先刪除這一類的變量栅哀,然后在刪除子節(jié)點(diǎn)中的變量。
我覺得node是一個(gè)抽象類而账,其中的方法大部分需要有繼承他的類來(lái)繼承胰坟。
2. Element
2.1 聲明
我們可以看到Element繼承自Node。
在Element中主要定義了ref泞辐, type笔横, attr, classStyle铛碑, style狠裹,event屬性。
2.2 appendChild
Element.prototype.appendChild = function (node) {
if (node.parentNode && node.parentNode !== this) {
return
}
if (!node.parentNode) {
linkParent(node, this)
insertIndex(node, this.children, this.children.length, true)
if (this.docId) {
registerNode(this.docId, node)
}
if (node.nodeType === 1) {
insertIndex(node, this.pureChildren, this.pureChildren.length)
if (this.docId) {
const listener = instanceMap[this.docId].listener
return listener.addElement(node, this.ref, -1)
}
}
}
else {
moveIndex(node, this.children, this.children.length, true)
if (node.nodeType === 1) {
const index = moveIndex(node, this.pureChildren, this.pureChildren.length)
if (this.docId && index >= 0) {
const listener = instanceMap[this.docId].listener
return listener.moveElement(node.ref, this.ref, index)
}
}
}
}
- 判斷要增加的父節(jié)點(diǎn)是否村鎮(zhèn)
- 若不存在
- 首先建立與父節(jié)點(diǎn)的聯(lián)系汽烦。
- 給這個(gè)節(jié)點(diǎn)賦予docid
- 如果節(jié)點(diǎn)類型是Element涛菠,則把此節(jié)點(diǎn)加至父節(jié)點(diǎn)的pureChidren中。
- 調(diào)取觀察器的增加元素的方法撇吞。
- 若存在
則刪除此元素俗冻,并且調(diào)用刪除事件。