<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] # 簡介 當Dom樹構建完成時,瀏覽器開始構建另一棵樹——渲染樹。渲染樹由元素顯示序列中的可見元素組成,它是文檔的可視化表示,構建這棵樹是為了以正確的順序繪制文檔內容。 Firefox將渲染樹中的元素稱為frames,WebKit則用renderer或渲染對象來描述這些元素。 <br> <br> # 渲染樹和Dom樹的關系 **渲染對象和Dom元素相對應,但這種對應關系不是一對一的**,不可見的Dom元素不會被插入渲染樹,例如head元素。另外,display屬性為none的元素也不會在渲染樹中出現(visibility屬性為hidden的元素將出現在渲染樹中)。 <br> **還有一些Dom元素對應幾個可見對象**,它們一般是一些具有復雜結構的元素,無法用一個矩形來描述。例如,select元素有三個渲染對象——一個顯示區域、一個下拉列表及一個按鈕。同樣,當文本因為寬度不夠而折行時,新行將作為額外的渲染元素被添加。另一個多個渲染對象的例子是不規范的html,根據css規范,一個行內元素只能僅包含行內元素或僅包含塊狀元素,在存在混合內容時,將會創建匿名的塊狀渲染對象包裹住行內元素。 <br> 一些渲染對象和所對應的Dom節點不在樹上相同的位置,例如,浮動和絕對定位的元素在文本流之外,在兩棵樹上的位置不同,渲染樹上標識出真實的結構,并用一個占位結構標識出它們原來的位置。 <br> ![](https://box.kancloud.cn/3e4ce70199dd6cc78e7dbd615bc2d774_731x396.png) <br> <br> # 創建樹的流程 Firefox中,表述為一個監聽Dom更新的監聽器,將frame的創建委派給Frame Constructor,這個構建器計算樣式(參看樣式計算)并創建一個frame。 <br>   Webkit中,計算樣式并生成渲染對象的過程稱為attachment,每個Dom節點有一個attach方法,attachment的過程是同步的,調用新節點的attach方法將節點插入到Dom樹中。 <br>   處理html和body標簽將構建渲染樹的根,這個根渲染對象對應被css規范稱為containing block的元素——包含了其他所有塊元素的頂級塊元素。它的大小就是viewport——瀏覽器窗口的顯示區域,Firefox稱它為viewPortFrame,webkit稱為RenderView,這個就是文檔所指向的渲染對象,樹中其他的部分都將作為一個插入的Dom節點被創建。 <br> <br> # 樣式計算 創建渲染樹需要計算出每個渲染對象的可視屬性,這可以通過計算每個元素的樣式屬性得到。 <br>   樣式包括各種來源的樣式表,行內樣式元素及html中的可視化屬性(例如bgcolor),可視化屬性轉化為css樣式屬性。 <br>   樣式表來源于瀏覽器默認樣式表,及頁面作者和用戶提供的樣式表——有些樣式是瀏覽器用戶提供的(瀏覽器允許用戶定義喜歡的樣式,例如,在Firefox中,可以通過在Firefox Profile目錄下放置樣式表實現)。 <br> 計算樣式的一些困難: 1. 樣式數據是非常大的結構,保存大量的樣式屬性會帶來內存問題。 2. 如果不進行優化,找到每個元素匹配的規則會導致性能問題,為每個元素查找匹配的規則都需要遍歷整個規則表,這個過程有很大的工作量。選擇符可能有復雜的結構,匹配過程如果沿著一條開始看似正確,后來卻被證明是無用的路徑,則必須去嘗試另一條路徑。 例如,下面這個復雜選擇符 ~~~   div div div div{…} ~~~ 這意味著規則應用到三個div的后代div元素,選擇樹上一條特定的路徑去檢查,這可能需要遍歷節點樹,最后卻發現它只是兩個div的后代,并不使用該規則,然后則需要沿著另一條路徑去嘗試 3. 應用規則涉及非常復雜的級聯,它們定義了規則的層次 <br> <br> ## 對規則進行處理以簡化匹配過程 樣式規則有幾個來源: * 外部樣式表或style標簽內的css規則 * 行內樣式屬性 * html可視化屬性(映射為相應的樣式規則)   后面兩個很容易匹配到元素,因為它們所擁有的樣式屬性和html屬性可以將元素作為key進行映射。 <br> 為了解決這個問題,可以先對規則進行處理,以使其更容易被訪問。 <br>   解析完樣式表之后,規則會根據選擇符添加一些hash映射,映射可以是根據id、class、標簽名或是任何不屬于這些分類的綜合映射。如果選擇符為id,規則將被添加到id映射,如果是class,則被添加到class映射,等等。 <br>   這個處理是匹配規則更容易,不需要查看每個聲明,我們能從映射中找到一個元素的相關規則,這個優化使在進行規則匹配時減少了95+%的工作量。 <br>   來看下面的樣式規則: ~~~ p.error {color:red} #messageDiv {height:50px} div {margin:5px} ~~~ <br> 第一條規則將被插入class映射,第二條插入id映射,第三條是標簽映射。 <br> 下面這個html片段: ~~~ <p class="error">an error occurred </p> <div id=" messageDiv">this is a message</div> ~~~ 我們首先找到p元素對應的規則,class映射將包含一個“error”的key,找到p.error的規則,div在id映射和標簽映射中都有相關的規則,剩下的工作就是找出這些由key對應的規則中哪些確實是正確匹配的。 例如,如果div的規則是 ~~~ table div {margin:5px} ~~~ 這也是標簽映射產生的,因為key是最右邊的選擇符,但它并不匹配這里的div元素,因為這里的div沒有table祖先。   Webkit和Firefox都會做這個處理。 <br> <br> # 以正確的級聯順序應用規則   樣式對象擁有對應所有可見屬性的屬性,如果特性沒有被任何匹配的規則所定義,那么一些特性可以從parent的樣式對象中繼承,另外一些使用默認值。 <br>   這個問題的產生是因為存在不止一處的定義,這里用級聯順序解決這個問題。 <br> ## 樣式表的級聯順序   一個樣式屬性的聲明可能在幾個樣式表中出現,或是在一個樣式表中出現多次,因此,應用規則的順序至關重要,這個順序就是級聯順序。根據css2的規范,級聯順序為(從低到高):   1. 瀏覽器聲明   2. 用戶聲明   3. 作者的一般聲明   4. 作者的important聲明   5. 用戶important聲明 <br>   瀏覽器聲明是最不重要的,用戶只有在聲明被標記為important時才會覆蓋作者的聲明。具有同等級別的聲明將根據specifity以及它們被定義時的順序進行排序。Html可視化屬性將被轉換為匹配的css聲明,它們被視為最低優先級的作者規則。 <br> ## Specifity Css2規范中定義的選擇符specifity如下: * 如果聲明來自style屬性,而不是一個選擇器的規則,則計1,否則計0(=a) * 計算選擇器中id屬性的數量(=b) * 計算選擇器中class及偽類的數量(=c) * 計算選擇器中元素名及偽元素的數量(=d) <br>   連接a-b-c-d四個數量(用一個大基數的計算系統)將得到specifity。這里使用的基數由分類中最高的基數定義。例如,如果a為14,可以使用16進制。不同情況下,a為17時,則需要使用阿拉伯數字17作為基數,這種情況可能在這個選擇符時發生html body div div …(選擇符中有17個標簽,一般不太可能)。   一些例子: ~~~ *{}/* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ li{}/* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ li:first-line {}/* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul li{}/* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul ol+li{}/* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ h1 + *[rel=up]{}/* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ ul ol li.red{}/* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ li.red.level{}/* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ #x34y{}/* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ ~~~ <br> <br> #參考資料 [瀏覽器工作原理(六):渲染樹構建](https://blog.csdn.net/lxcao/article/details/52862176)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看