深入:《从Chrome源码看浏览器如何构建DOM树》总结(未完成)

Smaller
###第一步:
DocumentLoader类中的startLoadingMainResource函数加载url返回的数据。

###第三步
######(5)开标签处理

对于处理例如标签,处理这个标签的任务是实例化一个HTMLHtmlElement元素,然后吧它的父元素指向document。

实际操作过程:

先创建一个html结点,再将其父结点和当前结点传入到一个任务队列。同时,它会被压入一个用于存放未遇到闭标签的所有开标签。

对于上面所说的任务队列,会有函数去判断任务的类型,然后进行不同的操作,比如本次执行的是insert任务,它会去执行一个插入的函数。再插入函数中,会先去检查父元素是否支持子元素,如果不支持,则直接返回(就像video标签不支持子元素)。接着再去调具体插入。

插入操作的idea:

  • 先设置子元素的父结点,也就是说会把html结点的父结点指向document

  • 如果没有lastChild,就会将这个子元素作为firstChild。

  • 但是由于上面已经有一个doctype的子结点了,也就是说已经有lastChild了,就会把这个子元素的previousSibling指向老的lastChild,老的lastChild的nextSibling指向它。

  • 最后把子元素设置为当前containerNode的lastChild。这样就建立起了html结点的父子兄弟关系。

######(6)闭标签处理
当遇到一个闭标签时,会把栈里的元素一直pop出来,知道pop到第一个和它标签名字一样的:
例如:

<!DOCTYPE html>
   <html>
      <head>
          <meta charset="utf-8"></meta>
      </head>
      <body>
          <div>
              <p><b>hello</b></p>
              <p>demo</p>
          </div>
       </body>
   </html>

把push和pop打印出来是这样的:

 push "HTML" m_stackDepth = 1
 push "HEAD" m_stackDepth = 2
 pop "HEAD" m_stackDepth = 1
 push "BODY" m_stackDepth = 2
 push "DIV" m_stackDepth = 3
 push "P" m_stackDepth = 4
 push "B" m_stackDepth = 5
 pop "B" m_stackDepth = 4
 pop "P" m_stackDepth = 3
 push "P" m_stackDepth = 4
 pop "P" m_stackDepth = 3
 pop "DIV" m_stackDepth = 2
 "tagName: body  |type: EndTag    |attr:              |text: "
 "tagName: html  |type: EndTag    |attr:              |text: "

但是如果有闭标签忘记写了,就会这样:

push "P" m_stackDepth = 4
push "B" m_stackDepth = 5
"tagName: p     |type: EndTag    |attr:              |text: "
pop "B" m_stackDepth = 4
pop "P" m_stackDepth = 3
push "B" m_stackDepth = 4
push "P" m_stackDepth = 5
pop "P" m_stackDepth = 4
pop "B" m_stackDepth = 3
pop "DIV" m_stackDepth = 2
push "B" m_stackDepth = 3

######(7)自定义标签的处理
可以把这个标签当作span标签

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章