上节我们分析了vdom的 Document节点, 这节我们继续阅读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(下一兄弟节点), previousSibling(上一兄弟节点)以及destroy方法。
destroy删除的原则是先删除这一类的变量,然后在删除子节点中的变量。
我觉得node是一个抽象类,其中的方法大部分需要有继承他的类来继承。
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)
}
}
}
}
- 判断要增加的父节点是否村镇
- 若不存在
- 首先建立与父节点的联系。
- 给这个节点赋予docid
- 如果节点类型是Element,则把此节点加至父节点的pureChidren中。
- 调取观察器的增加元素的方法。
- 若存在
则删除此元素,并且调用删除事件。