運行時的頁面構建過程

前言

本文是閱讀《JavaScipt忍者祕籍》的心得體會css

  • 瀏覽器是否會老是根據給定的html來渲染頁面?
  • web 應用一次能處理多少個事件?
  • 爲何瀏覽器使用事件隊列來處理事件?

1、web應用的生命週期

典型的生命週期當用戶輸入url,瀏覽器向服務器發送了請求服務器接收了請求而且返回一個由html,css,hmtl組成的響應瀏覽器接收了該響應後就開始了。html

而後瀏覽器開始根據響應構建頁面建立用戶界面。而後開始作事件處理,進入事件隊列的循環中,等待事件的發生,而後調用處理器。web

應用的生命週期隨這用戶關掉或者離開界面結束api

2、如何構建頁面?

  • 解析HTML代碼並構建文檔對象模型(DOM)
  • 執行JavaScript代碼

在頁面構建過程當中這兩個步驟會交替執行屢次。瀏覽器

#HTML解析和DOM構建

瀏覽器經過解析接收到的HTML代碼構建一個個HTML元素來構建DOM。bash

在這個過程當中每個HTML元素都被當成一個節點,除了根節點外每個節點都只有一個父節點,能夠有任意數量個子節點,同一個元素節點的子節點被稱做兄弟節點。服務器

以HTML爲藍本渲染DOM的時候還會自動修復一些錯誤。app

<html>
    <head>
        <div></div>
    </head>
    <body>
    <body>
</html>
複製代碼

在這裏咱們把內容元素div放到了header中。 dom

image

瀏覽器自動把它調整到了body中異步

直到咱們遇到了一種特殊類型的HTML元素——腳本元素,腳本元素中包括JavaScript代碼,當我們遇到了這種元素就必須中止DOM的渲染開始執行JavaScript代碼。

#執行JavaScript代碼

js代碼由瀏覽器引擎執行,firefox的Spidemonkey引擎,Chrome和Opera 和V8引擎和IE的Chakra引擎。js代碼的目的是提供動態頁面,瀏覽器經過全局對象提供了api使JavaScript引擎能夠與之交互並改變其內容。

#JavaScript中的全局對象

JavaScript對象中存在一個window對象,它表明了整個包含頁面的窗口。

它最重要的屬性是document,表明了當前頁面的dom。

window對象是老大,經過跟老大接觸咱們能夠獲取其餘全部的全局對象,全局變量和瀏覽器API的訪問途徑。咱們能夠在任何程度上改變DOM,修改,刪除,添加節點。

#全局代碼和函數代碼

位置上函數外的是全局變量,函數內的函數變量。

執行方式上去全局代碼會由JavaScript引擎以一種直接的方式自動執行,要想執行函數代碼就要被其餘代碼調用,能夠是全局代碼,也能夠是其餘函數,又或者是被瀏覽器調用。

在頁面構建階段,若是遇到了腳本節點,瀏覽器就會中止從HTML到DOM的節點,開始執行JavaScript代碼。看以下代碼

<body>
    
    <button id="button1" type="button"></button>
    <!--建立一個函數,點擊添加元素,給元素添加內容插入到dom節點。-->
    <script>
        function createButton(element, content) {
            var createMessage = window.document.createElement('div');
            createMessage.textContent = content;
            element.appendChild(createMessage);

        }
        var button1 = document.getElementById('button1');
        createButton(button1, '哈哈哈哈')
    </script>
    
    <div id="div1"></div>
    <!--建立一個點擊事件,調用以前建立的函數-->
    <script>
        window.document.body.onclick = function () {
            var div1 = document.getElementById('div1')
            createButton(div1, '笑一個吧~')
        }
    </script>
</body>
複製代碼

JavaScript幾乎能夠添加刪除修改全部的節點,可是它不能去動沒有建立的節點,因此爲了不這個問題,咱們要把JavaScript代碼放到頁面底部。

當JavaScript代碼執行結束後,瀏覽器就退出了JavaScript的執行模式繼續HTML到DOM的解析過程直到再次遇到腳本節點。重複以上過程。最後頁面建立階段就結束了。

而且在這個過程當中全部建立的全局變量都能正常被其餘腳本元素中的JavaScript代碼訪問到。緣由在於全局對象window對象在整個頁面的生存期當中。

3、事件處理

事件處理的重點在於一次只能執行一個代碼片斷,能夠想象一下食堂一次只能一我的打飯。

因爲一次只能執行一個代碼片斷,瀏覽器把觸發的事件依次推到了一個事件隊列中以這種方式來跟蹤還沒有處理的事件。

瀏覽器會檢查事件隊列頭,若是沒有找到就繼續檢查,若是找到了事件就取出該事件執行相應的事件處理器,重複執行。

此外放置事件的隊列是獨立在頁面構建階段和事件處理階段之外的。

#異步

事件是異步的,代碼的提早創建是爲了保證以後的執行。

#註冊事件處理器

  • 一個方法是把函數賦給某些特殊屬性
window.onload=function(){}
複製代碼
  • 使用內置方法 addEventListener
document.body.addEventListener("onclick",function(){})
複製代碼

使用後者的優點在於能夠註冊儘量多的事件,而前者只能註冊一個事件處理器

#處理事件的流程

觸發事件後,事件被推到事件隊列中。

image

解決問題

  • 瀏覽器是否會老是根據給定的html來渲染頁面?

是的。可是不只僅是THML,在頁面構建過程當中解析HTML成DOM和JavaScript代碼的執行是交替進行的(這裏不講css)

  • web 應用一次能處理多少個事件?

一次一個。因爲JavaScipt基於一個單線程的執行模型。

  • 爲何瀏覽器使用事件隊列來處理事件?

由於一次只能執行一個,因此爲了追蹤觸發的事件就使用了事件隊列,而且隊列是先進先出的頁很公平。

相關文章
相關標籤/搜索