好程式設計師分享Web前端知識之HTML
今天好程式設計師分享Web前端知識之HTML。Web前端技術由HTML、CSS和Javascript三大部分構成,而我們在學習它的時候往往是先從某一個點切入,然後不斷地接觸和學習新的知識點,因此對於初學者很難理清楚整個體系的脈絡結構。
1、BOM
BOM是BrowserObjectModel
的縮寫,即瀏覽器物件模型,當一個瀏覽器頁面初始化時,會在記憶體建立一個全域性的物件,用以描述當前視窗的屬性和狀態,這個全域性物件被稱為瀏覽器物件模型,即BOM。BOM的核心物件就是window,window
物件也是BOM的頂級物件,其中包含了瀏覽器的6個核心模組:
document-
即文件物件,渲染引擎在解析HTML程式碼時,會為每一個元素生成對應的DOM物件,由於元素之間有層級關係,因此整個HTML程式碼解析完以後,會生成一個由不同節點組成的樹形結構,俗稱DOM樹,document
用於描述DOM樹的狀態和屬性,並提供了很多操作DOM的API。
frames-HTML子框架,即在瀏覽器裡嵌入另一個視窗,父框架和子框架擁有獨立的作用域和上下文。
history-以棧(FIFO)的形式儲存著頁面被訪問的歷史記錄,頁面前進即入棧,頁面返回即出棧。
location-提供了當前視窗中載入的文件相關資訊以及一些導航功能。
navigator-用來描述瀏覽器本身,包括瀏覽器的名稱、版本、語言、系統平臺、使用者特性字串等資訊。
screen-提供了瀏覽器顯示螢幕的相關屬性,比如顯示螢幕的寬度和高度,可用寬度和高度。
2、DOM系統
DOM是DocumentObjectModel的縮寫,即文件物件模型,是所有瀏覽器公共遵守的標準,DOM
將HTML和XML文件對映成一個由不同節點組成的樹型結構,俗稱DOM樹。其核心物件是document,用於描述DOM樹的狀態和屬性,並提供對應的DOM操作API。隨著歷史的發展,DOM
被劃分為1級、2級、3級,共3個級別:
1級DOM-在1998年10月份成為W3C的提議,由DOM核心與DOM
HTML兩個模組組成。DOM核心能對映以XML為基礎的文件結構,允許獲取和操作文件的任意部分。DOM
HTML通過新增HTML專用的物件與函式對DOM核心進行了擴充套件。
2級DOM-鑑於1級DOM僅以對映文件結構為目標,DOM
2級面向更為寬廣。通過對原有DOM的擴充套件,2級DOM通過物件介面增加了對滑鼠和使用者介面事件(DHTML長期支援滑鼠與使用者介面事件)、範圍、遍歷(重複執行DOM文件)和層疊樣式表(CSS)的支援。同時也對DOM
1的核心進行了擴充套件,從而可支援XML名稱空間。
3級DOM-
通過引入統一方式載入和儲存文件和文件驗證方法對DOM進行進一步擴充套件,DOM3包含一個名為“DOM載入與儲存”的新模組,DOM核心擴充套件後可支援XML1.0的所有內容,包括XML
Infoset、XPath、和XMLBase。
瀏覽器對不同級別DOM的支援情況如下所示:
從圖中可以看出,移動端常用的Webkit核心瀏覽器目前只支援DOM2,而不支援DOM3。
3、事件系統
事件是使用者與頁面互動的基礎,到目前為止,DOM事件從PC端的滑鼠事件(mouse)發展到了移動端的觸控事件(touch)和
手勢事件(guesture),touch事件描述了手指在螢幕操作的每一個細節,guesture則是描述多手指操作時更為複雜的情況,總結如下:
第一根手指放下,觸發touchstart,除此之外什麼都不會發生
手指滑動時,觸發touchmove
第二根手指放下,觸發gesturestart
觸發第二根手指的touchstart
立即觸發gesturechange
任意手指移動,持續觸發gesturechange
第二根手指彈起時,觸發gestureend,以後將不會再觸發gesturechange
觸發第二根手指的touchend
觸發touchstart(多根手指在螢幕上,提起一根,會重新整理一次全域性touch)____
彈起第一根手指,觸發touchend
更多關於手勢事件的介紹請參考:
gesture事件處理複雜手勢
DOM2.0模型將事件處理流程分為三個階段,即事件捕獲階段、事件處理階段、事件冒泡階段,如圖所示:
事件捕獲:當用戶觸發點選事件後,頂層物件document就會發出一個事件流,從最外層的DOM節點向目標元素節點傳遞,最終到達目標元素。
事件處理:當到達目標元素之後,執行目標元素繫結的處理函式。如果沒有繫結監聽函式,則不做任何處理。
事件冒泡:事件流從目標元素開始,向最外層DOM節點傳遞,途中如果有節點綁定了事件處理函式,這些函式就會被執行。
利用事件冒泡原理可以實現事件委託
,所謂事件委託,就是在父元素上新增事件監聽器,用以監聽和處理子元素的事件,避免重複為子元素繫結相同的事件。當目標元素的事件被觸發以後,這個事件就從目標元素開始,向最外層元素傳遞,最終冒泡到父元素上,父元素再通過event.target
獲取到這個目標元素,這樣做的好處是,父元素只需繫結一個事件監聽,就可以對所有子元素的事件進行處理了,從而減少了不必要的事件繫結,對頁面效能有一定的提升。
4、HTML解析過程
瀏覽器載入html檔案以後,渲染引擎會從上往下,一步步來解析HTML標籤,大致過程如下:
使用者輸入網址,瀏覽器向伺服器發出請求,伺服器返回html檔案;
渲染引擎開始解析html標籤,並將標籤轉化為DOM節點,生成DOM樹;
如果head標籤中引用了外部css檔案,則發出css檔案請求,伺服器返回該檔案,該過程會阻塞後面的解析;
如果引用了外部js檔案,則發出js檔案請求,伺服器返回後立即執行該指令碼,這個過程也會阻塞html的解析;
引擎開始解析body裡面的內容,如果標籤裡引用了css樣式,就需要解析剛才下載好的css檔案,然後用css來設定標籤的樣式屬性,並生成渲染樹;
如果body中的img標籤引用了圖片資源,則立即向伺服器發出請求,此時引擎不會等待圖片下載完畢,而是繼續解析後面的標籤;
伺服器返回圖片檔案,由於圖片需要佔用一定的空間,會影響到後面元素的排版,因此引擎需要重新渲染這部分內容;
如果此時js指令碼中運行了style.display="none",佈局被改變,引擎也需要重新渲染這部分程式碼;
直到html結束標籤為止,頁面解析完畢。
5、重繪和迴流
當渲染樹中的一部分(或全部)因為元素的規模尺寸,佈局,隱藏等改變而需要重新構建。這就稱為迴流。比如上面的img檔案載入完成後就會引起迴流,每個頁面至少需要一次迴流,就是在頁面第一次載入的時候。
當渲染樹中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,比如background-color。則就叫稱為重繪。
從上面可以看出,迴流必將引起重繪,而重繪不一定會引起迴流。會引起重繪和迴流的操作如下:
新增、刪除元素(迴流+重繪)
隱藏元素,display:none(迴流+重繪),visibility:hidden(只重繪,不迴流)
移動元素,比如改變top,left的值,或者移動元素到另外一個父元素中。(重繪+迴流)
對style的操作(對不同的屬性操作,影響不一樣)
還有一種是使用者的操作,比如改變瀏覽器大小,改變瀏覽器的字型大小等(迴流+重繪)
另外,transform
操作不會引起重繪和迴流,是一種高效率的渲染。這是因為transform屬於合成屬性,對合成屬性進行transition/animation
動畫時將會建立一個合成層,這使得動畫元素在一個獨立的層中進行渲染,當元素的內容沒有發生改變,就沒必要進行重繪,瀏覽器會通過重新複合來建立動畫幀。
6、本地儲存
本地儲存最原始的方式就是cookie,cookie是存放在本地瀏覽器的一段文字,資料以鍵值對的形式儲存,可以設定過期時間。但是cookie
不適合大量資料的儲存,因為每請求一次頁面,cookie都會發送給伺服器,這使得cookie
速度很慢而且效率也不高。因此cookie的大小被限制為4k左右(不同瀏覽器可能不同,分HOST),如下所示:
Firefox和Safari允許cookie多達4097個位元組,包括名(name)、值(value)和等號。
Opera允許cookie多達4096個位元組,包括:名(name)、值(value)和等號。
InternetExplorer允許cookie多達4095個位元組,包括:名(name)、值(value)和等號。
在所有瀏覽器中,任何cookie大小超過限制都被忽略,且永遠不會被設定。
html5提供了兩種在客戶端儲存資料的新方法:localStorage和sessionStorage,它們都是以key/value
的形式來儲存資料,前者是永久儲存,後者的儲存期限僅限於瀏覽器會話(session),即當瀏覽器視窗關閉後,sessionStorage中的資料被清除。
localStorage的儲存空間大約5M左右(不同瀏覽器可能不同,分
HOST),這個相當於一個5M大小的前端資料庫,相比於cookie,可以節約頻寬,但localStorage在瀏覽器隱私模式下是不可讀取的,當儲存資料超過了localStorage
的儲存空間後會丟擲異常。
此外,H5還提供了逆天的Websql和
indexedDB,允許前端以關係型資料庫的方式來儲存本地資料,相對來說,這個功能目前應用的場景比較少,此處不作介紹。
7、瀏覽器快取機制
瀏覽器快取機制是指通過HTTP協議頭裡的Cache-Control(或Expires)和Last-Modified(或Etag)
等欄位來控制檔案快取的機制。
Cache-Control用於控制檔案在本地快取有效時長。最常見的,比如伺服器回包:Cache-Control:max-age=600
表示檔案在本地應該快取,且有效時長是600秒(從發出請求算起)。在接下來600秒內,如果有請求這個資源,瀏覽器不會發出HTTP
請求,而是直接使用本地快取的檔案。
Last-Modified是標識檔案在伺服器上的最新更新時間。下次請求時,如果檔案快取過期,瀏覽器通過If-Modified-Since
欄位帶上這個時間,傳送給伺服器,由伺服器比較時間戳來判斷檔案是否有修改。如果沒有修改,伺服器返回304告訴瀏覽器繼續使用快取;如果有修改,則返回200,同時返回最新的檔案。
Cache-Control通常與Last-Modified一起使用。一個用於控制快取有效時間,一個在快取失效後,向服務查詢是否有更新。
Cache-Control還有一個同功能的欄位:Expires。Expires的值一個絕對的時間點,如:Expires:Thu,10Nov
201508:45:11GMT,表示在這個時間點之前,快取都是有效的。
Expires是HTTP1.0標準中的欄位,Cache-Control是HTTP1.1
標準中新加的欄位,功能一樣,都是控制快取的有效時間。當這兩個欄位同時出現時,Cache-Control是高優化級的。
Etag也是和Last-Modified一樣,對檔案進行標識的欄位。不同的是,Etag
的取值是一個對檔案進行標識的特徵字串。在向伺服器查詢檔案是否有更新時,瀏覽器通過If-None-Match
欄位把特徵字串傳送給伺服器,由伺服器和檔案最新特徵字串進行匹配,來判斷檔案是否有更新。沒有更新回包304,有更新回包200。Etag和
Last-Modified可根據需求使用一個或兩個同時使用。兩個同時使用時,只要滿足基中一個條件,就認為檔案沒有更新。
另外有兩種特殊的情況:
手動重新整理頁面(F5),瀏覽器會直接認為快取已經過期(可能快取還沒有過期),在請求中加上欄位:Cache-Control:max-age=0,發包向伺服器查詢是否有檔案是否有更新。
強制重新整理頁面(Ctrl+F5),瀏覽器會直接忽略本地的快取(有快取也會認為本地沒有快取),在請求中加上欄位:Cache-Control:no-cache
(或Pragma:no-cache),發包向服務重新拉取檔案。
8、History
使用者訪問網頁的歷史記錄通常會被儲存在一個類似於棧的物件中,即history物件,點選返回就出棧,跳下一頁就入棧。它提供了以下方法來操作頁面的前進和後退:
window.history.back()返回到上一個頁面
window.history.forward()進入到下一個頁面
window.history.go([delta])跳轉到指定頁面
HTML5對HistoryApi進行了增強,新增了兩個Api和一個事件,分別是pushState、replaceState和
onpopstate:
pushState是往history物件裡新增一個新的歷史記錄,即壓棧。
replaceState是替換history物件中的當前歷史記錄。
當點選瀏覽器後退按鈕或js呼叫history.back都會觸發onpopstate事件。
與其類似的還有一個事件:onhashchange,onhashchange是老API,瀏覽器支援度高,本來是用來監聽hash變化的,但可以被利用來做客戶端前進和後退事件的監聽,而onpopstate是專門用來監聽瀏覽器前進後退的,不僅可以支援hash,非hash的同源
url也支援。
9、HTML5離線快取
HTML5離線快取又叫Application
Cache,是從瀏覽器的快取中分出來的一塊快取區,如果要在這個快取中儲存資料,可以使用一個描述檔案(manifestfile),列出要下載和快取的資源。
manifest檔案是簡單的文字檔案,它告知瀏覽器被快取的內容(以及不快取的內容)。manifest檔案可分為三個部分:
-CACHEMANIFEST-在此標題下列出的檔案將在首次下載後進行快取
-NETWORK-在此標題下列出的檔案需要與伺服器的連線,且不會被快取
-FALLBACK-在此標題下列出的檔案規定當頁面無法訪問時的回退頁面(比如404頁面)
離線快取為應用帶來三個優勢:
離線瀏覽-使用者可在應用離線時使用它們
速度-已快取資源載入得更快
減少伺服器負載-瀏覽器將只從伺服器下載更新過或更改過的資源。
10、Web語義化和SEO
Web語義化是指使用語義恰當的標籤,使頁面有良好的結構,頁面元素有含義,能夠讓人和搜尋引擎都容易理解。
SEO是指在瞭解搜尋引擎自然排名機制的基礎之上,對網站進行內部及外部的調整優化,改進網站在搜尋引擎中關鍵詞的自然排名,獲得更多的展現量,吸引更多目標客戶點選訪問網站,從而達到網際網路營銷及品牌建設的目標。
搜尋引擎通過爬蟲技術獲取的頁面就是由一堆html標籤組成的程式碼,人可以通過視覺化的方式來判斷頁面上哪些內容是重點,而機器做不到。
但搜尋引擎會根據標籤的含義來判斷內容的權重,因此,在合適的位置使用恰當的標籤,使整個頁面的語義明確,結構清晰,搜尋引擎才能正確識別頁面中的重要內容,並予以較高的權值。比如h1~h6這幾個標籤在SEO中的權值非常高,用它們作頁面的標題就是一個