中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

輸入URL后頁面會發生什么

發布時間:2022-02-25 10:35:02 來源:億速云 閱讀:104 作者:iii 欄目:開發技術

這篇文章主要介紹“輸入URL后頁面會發生什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“輸入URL后頁面會發生什么”文章能幫助大家解決問題。

構建 DOM 樹

由于瀏覽器無法直接理解 HTML字符串 ,因此將這一系列的字節流轉換為一種有意義并且方便操作的數據結構,這種數據結構就是DOM樹DOM樹本質上是一個以document為根節點的多叉樹。

那通過什么樣的方式來進行解析呢?

HTML文法的本質

首先,我們應該清楚把握一點: HTML 的文法并不是上下文無關文法

這里,有必要討論一下什么是上下文無關文法

在計算機科學的編譯原理學科中,有非常明確的定義:

若一個形式文法G = (N, Σ, P, S) 的產生式規則都取如下的形式:V-&w,則叫上下文無關語法。其中 V∈N ,w∈(N∪Σ)* 。

其中把 G = (N, Σ, P, S) 中各個參量的意義解釋一下:

  1. N 是非終結符(顧名思義,就是說最后一個符號不是它, 下面同理)集合。

  2. Σ 是終結符集合。

  3. P 是開始符,它必須屬于 N ,也就是非終結符。

  4. S 就是不同的產生式的集合。如 S -> aSb 等等。

通俗一點講,上下文無關的文法就是說這個文法中所有產生式的左邊都是一個非終結符。

看到這里,如果還有一點懵圈,我舉個例子你就明白了。

比如:

A -> B

這個文法中,每個產生式左邊都會有一個非終結符,這就是上下文無關的文法。在這種情況下,xBy一定是可以規約出xAy的。

我們下面看看看一個反例:

aA -> B
Aa -> B

這種情況就是不是上下文無關的文法,當遇到B的時候,我們不知道到底能不能規約出A,取決于左邊或者右邊是否有a存在,也就是說和上下文有關。

關于它為什么是非上下文無關文法,首先需要讓大家注意的是,規范的 HTML 語法,是符合上下文無關文法的,能夠體現它非上下文無關的是不標準的語法。在此我僅舉一個反例即可證明。

比如解析器掃描到form標簽的時候,上下文無關文法的處理方式是直接創建對應 form 的 DOM 對象,而真實的 HTML5 場景中卻不是這樣,解析器會查看 form 的上下文,如果這個 form 標簽的父標簽也是 form, 那么直接跳過當前的 form 標簽,否則才創建 DOM 對象。

常規的編程語言都是上下文無關的,而HTML卻相反,也正是它非上下文無關的特性,決定了HTML Parser并不能使用常規編程語言的解析器來完成,需要另辟蹊徑。

解析算法

HTML5 規范詳細地介紹了解析算法。這個算法分為兩個階段:

  1. 標記化。

  2. 建樹。

對應的兩個過程就是詞法分析語法分析

標記化算法

這個算法輸入為 HTML文本 ,輸出為HTML標記,也成為標記生成器。其中運用有限自動狀態機來完成。即在當當前狀態下,接收一個或多個字符,就會更新到下一個狀態。

<html>
  <body>
    Hello sanyuan
  </body>
</html>

通過一個簡單的例子來演示一下標記化的過程。

遇到<, 狀態為標記打開

接收[a-z]的字符,會進入標記名稱狀態

這個狀態一直保持,直到遇到>,表示標記名稱記錄完成,這時候變為數據狀態

接下來遇到body標簽做同樣的處理。

這個時候htmlbody的標記都記錄好了。

現在來到<body>中的>,進入數據狀態,之后保持這樣狀態接收后面的字符hello sanyuan

接著接收 </body> 中的<,回到標記打開, 接收下一個/后,這時候會創建一個end tag的token。

隨后進入標記名稱狀態, 遇到>回到數據狀態

接著以同樣的樣式處理 </body>。

建樹算法

之前提到過,DOM 樹是一個以document為根節點的多叉樹。因此解析器首先會創建一個document對象。標記生成器會把每個標記的信息發送給建樹器建樹器接收到相應的標記時,會創建對應的 DOM 對象。創建這個DOM對象后會做兩件事情:

  1. DOM對象加入 DOM 樹中。

  2. 將對應標記壓入存放開放(與閉合標簽意思對應)元素的棧中。

還是拿下面這個例子說:

<html>
  <body>
    Hello sanyuan
  </body>
</html>

首先,狀態為初始化狀態

接收到標記生成器傳來的html標簽,這時候狀態變為before html狀態。同時創建一個HTMLHtmlElement的 DOM 元素, 將其加到document根對象上,并進行壓棧操作。

接著狀態自動變為before head, 此時從標記生成器那邊傳來body,表示并沒有head, 這時候建樹器會自動創建一個HTMLHeadElement并將其加入到DOM樹中。

現在進入到in head狀態, 然后直接跳到after head

現在標記生成器傳來了body標記,創建HTMLBodyElement, 插入到DOM樹中,同時壓入開放標記棧。

接著狀態變為in body,然后來接收后面一系列的字符: Hello sanyuan。接收到第一個字符的時候,會創建一個Text節點并把字符插入其中,然后把Text節點插入到 DOM 樹中body元素的下面。隨著不斷接收后面的字符,這些字符會附在Text節點上。

現在,標記生成器傳過來一個body的結束標記,進入到after body狀態。

標記生成器最后傳過來一個html的結束標記, 進入到after after body的狀態,表示解析過程到此結束。

容錯機制

講到HTML5規范,就不得不說它強大的寬容策略, 容錯能力非常強,雖然大家褒貶不一,不過我想作為一名資深的前端工程師,有必要知道HTML Parser在容錯方面做了哪些事情。

接下來是 WebKit 中一些經典的容錯示例,發現有其他的也歡迎來補充。

1.使用</br>而不是<br>

if (t->isCloseTag(brTag) && m_document->inCompatMode()) {
  reportError(MalformedBRError);
  t->beginTag = true;
}

全部換為<br>的形式。

2.表格離散

<table>
  <table>
    <tr><td>inner table</td></tr>
  </table>
  <tr><td>outer table</td></tr>
</table>

WebKit會自動轉換為:

<table>
    <tr><td>outer table</td></tr>
</table>
<table>
    <tr><td>inner table</td></tr>
</table>

3.表單元素嵌套

這時候直接忽略里面的form

樣式計算

關于CSS樣式,它的來源一般是三種:

  1. link標簽引用

  2. style標簽中的樣式

  3. 元素的內嵌style屬性

格式化樣式表

首先,瀏覽器是無法直接識別 CSS 樣式文本的,因此渲染引擎接收到 CSS 文本之后第一件事情就是將其轉化為一個結構化的對象,即styleSheets。

這個格式化的過程過于復雜,而且對于不同的瀏覽器會有不同的優化策略,這里就不展開了。

在瀏覽器控制臺能夠通過document.styleSheets來查看這個最終的結構。當然,這個結構包含了以上三種CSS來源,為后面的樣式操作提供了基礎。

標準化樣式屬性

有一些 CSS 樣式的數值并不容易被渲染引擎所理解,因此需要在計算樣式之前將它們標準化,如em->px,red->#ff0000,bold->700等等。

計算每個節點的具體樣式

樣式已經被格式化標準化,接下來就可以計算每個節點的具體樣式信息了。

其實計算的方式也并不復雜,主要就是兩個規則: 繼承層疊

每個子節點都會默認繼承父節點的樣式屬性,如果父節點中沒有找到,就會采用瀏覽器默認樣式,也叫UserAgent樣式。這就是繼承規則,非常容易理解。

然后是層疊規則,CSS 最大的特點在于它的層疊性,也就是最終的樣式取決于各個屬性共同作用的效果,甚至有很多詭異的層疊現象,看過《CSS世界》的同學應該對此深有體會,具體的層疊規則屬于深入 CSS 語言的范疇,這里就不過多介紹了。

不過值得注意的是,在計算完樣式之后,所有的樣式值會被掛在到window.computedStyle當中,也就是可以通過JS來獲取計算后的樣式,非常方便。

生成布局樹

現在已經生成了DOM樹DOM樣式,接下來要做的就是通過瀏覽器的布局系統確定元素的位置,也就是要生成一棵布局樹(Layout Tree)。

布局樹生成的大致工作如下:

  1. 遍歷生成的 DOM 樹節點,并把他們添加到布局樹中

  2. 計算布局樹節點的坐標位置。

值得注意的是,這棵布局樹值包含可見元素,對于 head標簽和設置了display: none的元素,將不會被放入其中。

有人說首先會生成Render Tree,也就是渲染樹,其實這還是 16 年之前的事情,現在 Chrome 團隊已經做了大量的重構,已經沒有生成Render Tree的過程了。而布局樹的信息已經非常完善,完全擁有Render Tree的功能。

之所以不講布局的細節,是因為它過于復雜,一一介紹會顯得文章過于臃腫,不過大部分情況下我們只需要知道它所做的工作是什么即可,如果想深入其中的原理,知道它是如何來做的,我強烈推薦你去讀一讀人人FED團隊的文章從Chrome源碼看瀏覽器如何layout布局。

關于“輸入URL后頁面會發生什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

url
AI

鹿邑县| 长宁区| 罗平县| 万荣县| 双辽市| 壶关县| 长武县| 宁乡县| 怀柔区| 新蔡县| 拜城县| 柘荣县| 新龙县| 南投县| 海宁市| 崇阳县| 长白| 盱眙县| 龙州县| 志丹县| 密云县| 界首市| 闽清县| 双桥区| 蓬安县| 宁明县| 梅州市| 宜都市| 永康市| 浑源县| 万源市| 宣武区| 淳化县| 莱州市| 抚顺县| 锦屏县| 晋江市| 麻栗坡县| 大冶市| 台中市| 邳州市|