知識精簡

Web前端知識體系精簡javascript

Web前端技術由html、css和 javascript三大部分構成,是一個龐大而複雜的技術體系,其複雜程度不低於任何一門後端語言。而咱們在學習它的時候每每是先從某一個點切入,而後不斷地接觸和學習新的知識點,所以對於初學者很難理清楚整個體系的脈絡結構。本文將對Web前端知識體系進行簡單的梳理,對應的每一個知識點點到爲止,不做詳細介紹。目的是幫助你們審查本身的知識結構是否完善,若有遺漏或不正確的地方,但願共勉。

1、JAVASCRIPT 篇css

0、基礎語法html

Javascript 基礎語法包括:變量聲明、數據類型、函數、控制語句、內置對象等。前端

在ES5 中,變量聲明有兩種方式,分別是 var 和 function ,var
用於聲明普通的變量,接收任意類型,function用於聲明函數。另外,ES6 新增了 let、const、import 和 class
等四個命令,分別用以聲明 普通變量、靜態變量、模塊 和 類 。html5

JS數據類型共有六種,分別是 String、Number、Boolean、Null、Undefined 和 Object 等, 另外,ES6新增了
Symbol 類型。其中,Object 是引用類型,其餘的都是原始類型(Primitive Type)。java

原始類型也稱爲基本類型或簡單類型,由於其佔據空間固定,是簡單的數據段,爲了便於提高變量查詢速度,將其存儲在棧(stack)中(按值訪問)。爲了便於操做這類數據,ECMAScript
提供了 3 個 基本包裝類型 :Boolean、Number 和 String
。基本包裝類型是一種特殊的引用類型,每當讀取一個基本類型值的時候,JS內部就會建立一個對應的包裝對象,從而能夠調用一些方法來操做這些數據。web

引用類型因爲其值的大小會改變,因此不能將其存放在棧中,不然會下降變量查詢速度,所以其存儲在堆(heap)中,存儲在變量處的值是一個指針,指向存儲對象的內存處(按址訪問),對於引用類型的值,能夠爲其添加屬性和方法,也能夠改變和刪除其屬性和方法;但基本類型不能夠添加屬性和方法。ajax

Javascript 能夠經過 typeof 來判斷原始數據類型,但不能判斷引用類型,要知道引用類型的具體類型,須要經過 Object 原型上的
toString 方法來判斷。正則表達式

JS中的函數存在着三種角色:普通函數、構造函數(類,具備屬性和方法)、對象方法。同一個函數,調用方式不一樣,函數的做用不同,所扮演的角色也不同。直接調用時就是普通函數,經過new建立對象時就是構造函數,經過對象調用時就是方法。sql

JS經常使用的內置對象有window、Date、Array、JSON、RegExp
等,window是瀏覽器在執行腳本時建立的一個全局對象,主要描述瀏覽器窗口相關的屬性和狀態,這個後面會講到,Date 和 Array
使用場景最多,JSON主要用於對象的序列化和反序列化,還有一個做用就是實現對象的深拷貝。RegExp 即正則表達式,是處理字符串的利器。

一、函數原型鏈

JS是一種基於對象的語言,但在ES6 以前是不支持繼承的,爲了具有繼承的能力,Javascript 在 函數對象
上創建了原型對象prototype,並以函數對象爲主線,從上至下,在JS內部構建了一條 原型鏈 。原型鏈把一個個獨立的對象聯繫在一塊兒,Object
則是全部對象的祖宗, 任何對象所創建的原型鏈最終都指向了Object,並以 Object 終結。 ****

簡單來講就是創建了變量查找機制,當訪問一個對象的屬性時,先查找對象自己是否存在,若是不存在就去該對象所在的原型連上去找,直到Object對象爲止,若是都沒有找到該屬性纔會返回undefined。所以,咱們能夠經過原型鏈來實現JS繼承。

二、函數做用域

函數做用域就是變量在聲明它們的函數體以及這個函數體嵌套的任意函數體內都是有定義的。所以, JS中沒有塊級做用域,只有函數做用域
,這種設計致使JS中出現了 變量提高 的問題。簡單來講就是,將變量聲明提高到它所在做用域的最開始的部分,爲了解決變量提高帶來的反作用,ES6新增了
let 命令來聲明變量,let 所聲明的變量只在 let 命令所在的代碼塊內有效,因此不存在變量提高問題。

三、this 指針

this 指針存在於函數中,用以標識函數運行時所處的上下文。函數的類型不一樣,this指向規則也不同:對於普通函數,this
始終指向全局對象window;對於構造函數,this則指向新建立的對象;對於方法,this指向調用該方法的對象。另外,Function對象也提供了call、apply
和 bind 等方法來改變函數的 this 指向,其中,call 和 apply 主動執行函數,bind通常在事件回調中使用,而 call 和 apply
的區別只是參數的傳遞方式不一樣。

若是往深的去理解,不管什麼函數,this是否被改變, 本質上,this 均指向觸發函數運行時的那個對象。而在函數運行時,this 的值是不能被改變的。

四、new 操做符

函數的建立有三種方式,即 顯式聲明、匿名定義 和 new Function()
。前面提到,JS中的函數便可以是函數,也能夠是方法,還能夠是構造函數。當使用new來建立對象時,該函數就是構造函數,JS將新對象的原型鏈指向了構造函數的原型對象,因而就在新對象和函數對象之間創建了一條原型鏈,經過新對象能夠訪問到函數對象原型prototype中的方法和屬性。

五、閉包

通俗來說,閉包是一個具備獨立做用域的靜態執行環境。和函數做用域不一樣的是,閉包的做用域是靜態的,能夠永久保存局部資源,而函數做用域只存在於運行時,函數執行結束後當即銷燬。所以,閉包能夠造成一個獨立的執行過程,關於閉包更

六、單線程和異步隊列

Javascript
是單線程語言,在瀏覽器中,當JS代碼被加載時,瀏覽器會爲其分配一個主線程來執行任務(函數),主線程會造成一個全局執行環境,執行環境在棧中採用後進先出(LIFO)的順序來執行代碼塊,以保證全部的函數能按照正確的順序被執行。

但在瀏覽器中,有一些任務是很是耗時的,好比ajax請求、定時器、事件等,爲了保證非耗時任務不受影響,Javascript
在執行環境中維護了一個異步隊列(也叫工做線程),並將這些耗時任務放入隊列中進行等待,這些任務的執行時機並不肯定,只有當主線程的任務執行完成之後,主線程纔會去檢查異步隊列中的任務是否須要開始執行。

JS中的 setTimeout 和 setInterval 就是典型的異步操做,它們會被放入異步隊列中等待,即便 setTimeout(0)
也不會被當即執行,須要等到當前同步任務結束後纔會被執行。

七、異步通訊 Ajax技術

Ajax是瀏覽器專門用來和服務器進行交互的異步通信技術,其核心對象是XMLHttpRequest,經過該對象能夠建立一個Ajax請求。Ajax請求是一個耗時的異步操做,當請求發出之後,Ajax
提供了兩個狀態位來描述請求在不一樣階段的狀態,這兩個狀態位分別是 readyState 和 status ,readyState 經過
5個狀態碼來描述一個請求的5個階段:

0 - 請求未發送,初始化階段

1 - 請求發送中,服務器還未收到請求

2 - 請求發送成功,服務器已收到請求

3 - 服務器處理完成,開始響應請求,傳輸數據

4 - 客戶端收到請求,並完成了數據下載,生成了響應對象

status 用於描述服務端對請求處理的狀況,200 表示正確響應了請求,404 表示服務器找不到資源,500 表明服務器內部異常等等。

Ajax對象還能夠設置一個timeout 值,表明超時時間,切記:timeout 只會影響
readyState,而不會影響status,由於超時只會中斷數據傳輸,但不會影響服務器的處理結果。 若是 timeout 設置的不合理,就會致使響應碼
status 是200,但 response裏卻沒有數據,這種狀況就是服務器正確響應了請求,但數據的下載被超時中斷了。

爲了防止XSS攻擊,瀏覽器對Ajax請求作了限制,不容許Ajax 跨域請求服務器,只容許請求和當前地址同域的服務器資源。但不限制腳本和標籤發送跨域請求,好比
script 和 img 標籤,所以能夠利用腳本跨域能力來實現跨域請求,即JSONP 的原理。

JSONP雖然能夠解決跨域問題,但只能是get請求,而且沒有有效的錯誤捕獲機制,爲了解決這個問題,XMLHttpRequest Level2 提出了
CORS 模型,即 跨域資源共享, 它不是一個新的API,而是一個標準規範,當瀏覽器發現該請求須要跨域時,就會自動在頭信息中添加一個 Origin
字段,用以說明本次請求來自哪一個源。服務器根據這個值,決定是否贊成此次請求。

隨着移動端的快速發展,Web技術的應用場景正在變得愈來愈複雜, 關注點分離 原則在系統設計層面就顯得愈來愈重要,而XMLHttpRequest 是
Ajax 最古老的一個接口,於是不太符合現代化的系統設計理念。所以,瀏覽器提供了一個新的 Ajax 接口,即 Fetch API ,Fetch
API 是基於Promise 思想設計的,更符合關注點分離原則。

八、模塊化

歷史上,Javascript 規範一直沒有模塊(module)體系,即沒法將一個大程序拆分紅互相依賴的小文件,再用簡單的方法拼裝起來。在 ES6
以前,爲了實現JS模塊化編程,社區制定了一些模塊加載方案,最主要有 CMD 和 AMD 兩種,分別以commonjs 和 requirejs爲表明。ES6
在語言標準的層面上,實現了模塊化編程,其設計思想是,儘可能靜態化,使得編譯時就能肯定模塊的依賴關係,即編譯時加載,而CMD和AMD是在運行時肯定依賴關係,即運行時加載。

九、Node.js

Node.js 是一個基於 Chrome V8 引擎的 JavaScript
運行環境,它的運行不依賴於瀏覽器做爲宿主環境,而是和服務端程序同樣能夠獨立的運行,這使得JS編程第一次從客戶端被帶到了服務端,Node.js在服務端的優點是,它採用單線程和異步I/O模型,實現了一個高併發、高性能的運行時環境。相比傳統的多線程模型,Node.js實現簡單,而且能夠減小資源開銷。

十、ES6

ES6 是 ECMAScript 6.0
的簡寫,即Javascript語言的下一代標準,已經在2015年6月正式發佈了,它的目標是讓JS可以方便的開發企業級大型應用程序,所以,ES6的一些規範正在逐漸向Java、C#等後端語言標準靠近。ES6
規範中,比較重大的變化有如下幾個方面:

新增 let、const 命令 來聲明變量,和var 相比,let
聲明的變量不存在變量提高問題,但沒有改變JS弱類型的特色,依然能夠接受任意類型變量的聲明;const
聲明的變量不容許在後續邏輯中改變,提升了JS語法的嚴謹性。

新增解構賦值、rest語法、箭頭函數,這些都是爲了讓代碼看起來更簡潔,而包裝的語法糖。

新增模塊化,這是JS走向規範比較重要的一步,讓前端更方便的實現工程化。

新增類和繼承的概念,配合模塊化,JS也能夠實現高複用、高擴展的系統架構。

新增模板字符串功能,高效簡潔,結束拼接字符串的時代。

新增Promise對象,解決異步回調多層嵌套的問題。

2、CSS 篇

一、CSS選擇器

CSS選擇器即經過某種規則來匹配相應的標籤,併爲其設置CSS樣式,經常使用的有類選擇器、標籤選擇器、ID選擇器、後代選擇器、羣組選擇器、僞類選擇器(before/after)、兄弟選擇器(+~)、屬性選擇器等等。

二、CSS Reset

HTML
標籤在不設置任何樣式的狀況下,也會有一個默認的CSS樣式,而不一樣內核瀏覽器對於這個默認值的設置則不盡相同,這樣可能會致使同一套代碼在不一樣瀏覽器上的顯示效果不一致,而出現兼容性問題。所以,在初始化時,須要對經常使用標籤的樣式進行初始化,使其默認樣式統一,這就是CSS
Reset ,即CSS樣式重置,好比:*{margin:0,padding:0} 就是最簡單CSS Reset, 關於CSS重置請參考:
Neat.css

三、盒子佈局

盒子模型是CSS比較重要的一個概念,也是CSS 佈局的基石。
常見的盒子模型有塊級盒子(block)和行內盒子(inline-block),與盒子相關的幾個屬性有:margin、border、padding和content
等,這些屬性的做用是設置盒子與盒子之間的關係以及盒子與內容之間的關係。其中,只有普通文檔流中塊級盒子的垂直外邊距纔會發生合併,而行內盒子、浮動盒子或絕對定位之間的外邊距不會合並。另外,box-sizing
屬性的設置會影響盒子width和height的計算。

四、浮動佈局

設置元素的 float 屬性值爲 left 或
right,就能使該元素脫離普通文檔流,向左或向右浮動。通常在作宮格佈局時會用到,若是子元素所有設置爲浮動,則父元素是塌陷的,這時就須要清除浮動,清除浮動的方法也不少,經常使用的方法是在元素末尾加空元素設置clear:both,
更高級一點的就給父容器設置before/after來模擬一個空元素,還能夠直接設置overflow屬性爲auto/hidden來清除浮動。除浮動能夠實現宮格佈局,行內盒子(inline-block)和table也能夠實現一樣的效果。

五、定位佈局

設置元素的position屬性值爲 relative/absolute/fixed,就可使該元素脫離文檔流,並以某種參照座標進行偏移。其中,releave
是相對定位,它以本身原來的位置進行偏移,偏移後,原來的空間不會被其餘元素佔用;absolute
是絕對定位,它以離本身最近的定位父容器做爲參照進行偏移;爲了對某個元素進行定位,經常使用的方式就是設置父容器的poistion:relative,由於相對定位元素在不設置
top 和 left 值時,不會對元素位置產生影響;fixed
即固定定位,它則以瀏覽器窗口爲參照物,PC網頁底部懸停的banner通常均可以經過fixed定位來實現,但fixed屬性在移動端有兼容性問題,所以不推薦使用,可替代的方案是:絕對定位+內部滾動。

六、彈性佈局

彈性佈局即Flex佈局,定義了flex的容器一個可伸縮容器,首先容器自己會根據容器中的元素動態設置自身大小;而後當Flex容器被應用一個大小時(width和height),將會自動調整容器中的元素適應新大小。Flex容器也能夠設置伸縮比例和固定寬度,還能夠設置容器中元素的排列方向(橫向和縱向)和是否支持元素的自動換行。有了這個神器,作頁面佈局的能夠方便不少了。注意,設爲Flex佈局之後,子元素的float、clear和vertical-align
屬性將失效。

七、CSS3 動畫

CSS3中規範引入了兩種動畫,分別是 transition 和 animation,transition
可讓元素的CSS屬性值的變化在一段時間內平滑的過渡,造成動畫效果,爲了使元素的變換更加豐富多彩,CSS3還引入了transfrom
屬性,它能夠經過對元素進行 平移(translate)、旋轉(rotate)、放大縮小(scale)、傾斜(skew)
等操做,來實現2D和3D變換效果。transiton 還有一個結束事件
transitionEnd,該事件是在CSS完成過渡後觸發,若是過渡在完成以前被移除,則不會觸發transitionEnd 。

animation 須要設置一個@keyframes,來定義元素以哪一種形式進行變換,
而後再經過動畫函數讓這種變換平滑的進行,從而達到動畫效果,動畫能夠被設置爲永久循環演示。設置 animation-play-state:paused
能夠暫停動畫,設置 animation-fill-mode:forwards
可讓動畫完成後定格在最後一幀。另外,還能夠經過JS監聽animation的開始、結束和重複播放時的狀態,分別對應三個事件,即
animationStart、animationEnd、animationIteration 。注意,當播放次數設置爲1時,不會觸發
animationIteration 。

和 transition相比,animation 設置動畫效果更靈活更豐富,還有一個區別是:transition
只能經過主動改變元素的css值才能觸發動畫效果,而animation一旦被應用,就開始執行動畫。另外,HTML5 還新增了一個動畫API,即
requestAnimationFrame,它經過JS來調用,並按照屏幕的繪製頻率來改變元素的CSS屬性,從而達到動畫效果。

八、BFC 連接: http://www.zhangxinxu.com/wordpress/2015/02/css-deep-understand-flow-bfc-column-two-auto-layout/

BFC是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面元素。好比:內部滾動就是一個BFC,當一個父容器的overflow-y設置爲auto時,而且子容器的長度大於父容器時,就會出現內部滾動,不管內部的元素怎麼滾動,都不會影響父容器之外的佈局,這個父容器的渲染區域就叫BFC。知足下列條件之一就可觸發BFC:

根元素,即HTML元素

float的值不爲none

overflow的值不爲visible

display的值爲inline-block、table-cell、table-caption

position的值爲absolute或fixed

九、Sprite,Iconfont,@font-face

對於大型站點,爲了減小http請求的次數,通常會將經常使用的小圖標排到一個大圖中,頁面加載時只需請求一次網絡,
而後在css中經過設置background-position來控制顯示所須要的小圖標,這就是Sprite圖。

Iconfont,即字體圖標,就是將經常使用的圖標轉化爲字體資源存在文件中,經過在CSS中引用該字體文件,而後能夠直接用控制字體的css屬性來設置圖標的樣式,字體圖標的好處是節省網絡請求、其大小不受屏幕分辨率的影響,而且能夠任意修改圖標的顏色。

@font-face是CSS3中的一個模塊,經過@font-face能夠定義一種全新的字體,而後就能夠經過css屬性font-family來使用這個字體了,即便操做系統沒有安裝這種字體,網頁上也會正常顯示出來。

十、CSS Hack

早期,不一樣內核瀏覽器對CSS屬性的解析存在着差別,致使顯示效果不一致,好比 margin
屬性在ie6中顯示的距離會比其餘瀏覽器中顯示的距離寬2倍,也就是說margin-left:20px;在ie6中距左側元素的實際顯示距離是40px,而在非ie6的瀏覽器上顯示正常。所以,若是要想讓全部瀏覽器中都顯示是20px的寬度,就須要在CSS樣式中加入一些特殊的符號,讓不一樣的瀏覽器識別不一樣的符號,以達到應用不一樣的CSS樣式的目的,這種方式就是css
hack, 對於ie6中的margin應用hack就會變成這樣:.el {margin-left:20px;_margin-left:10px}

兼容各大瀏覽器的 css hack 以下:

3、HTML 篇

一、BOM

BOM 是 Browser Object Model
的縮寫,即瀏覽器對象模型,當一個瀏覽器頁面初始化時,會在內存建立一個全局的對象,用以描述當前窗口的屬性和狀態,這個全局對象被稱爲瀏覽器對象模型,即BOM。BOM的核心對象就是window,window
對象也是BOM的頂級對象,其中包含了瀏覽器的 6個核心模塊:

document -
即文檔對象,渲染引擎在解析HTML代碼時,會爲每個元素生成對應的DOM對象,因爲元素之間有層級關係,所以整個HTML代碼解析完之後,會生成一個由不一樣節點組成的樹形結構,俗稱DOM樹,document
用於描述DOM樹的狀態和屬性,並提供了不少操做DOM的API。

frames - HTML 子框架,即在瀏覽器裏嵌入另外一個窗口,父框架和子框架擁有獨立的做用域和上下文。

history - 以棧(FIFO)的形式保存着頁面被訪問的歷史記錄,頁面前進即入棧,頁面返回即出棧。

location - 提供了當前窗口中加載的文檔相關信息以及一些導航功能。

navigator - 用來描述瀏覽器自己,包括瀏覽器的名稱、版本、語言、系統平臺、用戶特性字符串等信息。

screen - 提供了瀏覽器顯示屏幕的相關屬性,好比顯示屏幕的寬度和高度,可用寬度和高度。

二、DOM 系統

DOM 是 Document Object Model 的縮寫,即 文檔對象模型,是全部瀏覽器公共遵照的標準,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、和XML Base。

瀏覽器對不一樣級別DOM的支持狀況以下所示:

從圖中能夠看出,移動端經常使用的 webkit 內核瀏覽器目前只支持DOM2,而不支持DOM3 。

三、事件系統

事件是用戶與頁面交互的基礎,到目前爲止,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
獲取到這個目標元素,這樣作的好處是,父元素只需綁定一個事件監聽,就能夠對全部子元素的事件進行處理了,從而減小了沒必要要的事件綁定,對頁面性能有必定的提高。

四、HTML解析過程 ****

瀏覽器加載 html 文件之後,渲染引擎會從上往下,一步步來解析HTML標籤,大體過程以下:

用戶輸入網址,瀏覽器向服務器發出請求,服務器返回html文件;

渲染引擎開始解析 html 標籤,並將標籤轉化爲DOM節點,生成 DOM樹;

若是head 標籤中引用了外部css文件,則發出css文件請求,服務器返回該文件,該過程會阻塞後面的解析;

若是引用了外部 js 文件,則發出 js 文件請求,服務器返回後當即執行該腳本,這個過程也會阻塞html的解析;

引擎開始解析 body 裏面的內容,若是標籤裏引用了css 樣式,就須要解析剛纔下載好的css文件,而後用css來設置標籤的樣式屬性,並生成渲染樹;

若是 body 中的 img 標籤引用了圖片資源,則當即向服務器發出請求,此時引擎不會等待圖片下載完畢,而是繼續解析後面的標籤;

服務器返回圖片文件,因爲圖片須要佔用必定的空間,會影響到後面元素的排版,所以引擎須要從新渲染這部份內容;

若是此時 js 腳本中運行了 style.display="none",佈局被改變,引擎也須要從新渲染這部分代碼;

直到 html 結束標籤爲止,頁面解析完畢。

五、重繪 和 迴流

當渲染樹中的一部分(或所有)由於元素的規模尺寸,佈局,隱藏等改變而須要從新構建。這就稱爲迴流。好比上面的img文件加載完成後就會引發迴流,每一個頁面至少須要一次迴流,就是在頁面第一次加載的時候。

當渲染樹中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,好比 background-color。則就叫稱爲重繪。

從上面能夠看出,迴流必將引發重繪,而重繪不必定會引發迴流。會引發重繪和迴流的操做以下:

添加、刪除元素(迴流+重繪)

隱藏元素,display:none(迴流+重繪),visibility:hidden(只重繪,不迴流)

移動元素,好比改變top,left的值,或者移動元素到另一個父元素中。(重繪+迴流)

對style的操做(對不一樣的屬性操做,影響不同)

還有一種是用戶的操做,好比改變瀏覽器大小,改變瀏覽器的字體大小等(迴流+重繪)

另外,transform
操做不會引發重繪和迴流,是一種高效率的渲染。這是由於transform屬於合成屬性,對合成屬性進行transition/animation
動畫時將會建立一個合成層,這使得動畫元素在一個獨立的層中進行渲染,當元素的內容沒有發生改變,就不必進行重繪,瀏覽器會經過從新複合來建立動畫幀。

六、本地存儲

本地存儲最原始的方式就是 cookie,cookie 是存放在本地瀏覽器的一段文本,數據以鍵值對的形式保存,能夠設置過時時間。 可是 cookie
不適合大量數據的存儲,由於每請求一次頁面,cookie 都會發送給服務器,這使得 cookie
速度很慢並且效率也不高。所以cookie的大小被限制爲4k左右(不一樣瀏覽器可能不一樣,分HOST),以下所示:

Firefox和Safari容許cookie多達4097個字節,包括名(name)、值(value) 和 等號。

Opera容許cookie多達4096個字節,包括:名(name)、值(value) 和 等號。

Internet Explorer容許cookie多達4095個字節,包括:名(name)、值(value) 和 等號。

在全部瀏覽器中,任何cookie大小超過限制都被忽略,且永遠不會被設置。

html5 提供了兩種在客戶端存儲數據的新方法:localStorage 和 sessionStorage, 它們都是以key/value
的形式來存儲數據,前者是永久存儲,後者的存儲期限僅限於瀏覽器會話(session),即當瀏覽器窗口關閉後,sessionStorage中的數據被清除。

localStorage的存儲空間大約5M左右(不一樣瀏覽器可能不一樣,分
HOST),這個至關於一個5M大小的前端數據庫,相比於cookie,能夠節約帶寬,但localStorage在瀏覽器隱私模式下是不可讀取的,當存儲數據超過了localStorage
的存儲空間後會拋出異常。

此外,H5還提供了逆天的websql和
indexedDB,容許前端以關係型數據庫的方式來存儲本地數據,相對來講,這個功能目前應用的場景比較少,此處不做介紹。

七、瀏覽器緩存機制

瀏覽器緩存機制是指經過 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, 10 Nov
2015 08:45:11 GMT,表示在這個時間點以前,緩存都是有效的。

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),發包向服務從新拉取文件。

八、History

用戶訪問網頁的歷史記錄一般會被保存在一個相似於棧的對象中,即history對象,點擊返回就出棧,跳下一頁就入棧。 它提供瞭如下方法來操做頁面的前進和後退:

window.history.back( ) 返回到上一個頁面

window.history.forward( ) 進入到下一個頁面

window.history.go( [delta] ) 跳轉到指定頁面

HTML5 對History Api 進行了加強,新增了兩個Api 和一個事件,分別是pushState、replaceState 和
onpopstate:

pushState是往history對象裏添加一個新的歷史記錄,即壓棧。

replaceState 是替換history對象中的當前歷史記錄。

當點擊瀏覽器後退按鈕或 js調用history.back 都會觸發 onpopstate 事件。

與其相似的還有一個事件:onhashchange,onhashchange是老API,瀏覽器支持度高,原本是用來監聽hash變化的,但能夠被利用來作客戶端前進和後退事件的監聽,而onpopstate是專門用來監聽瀏覽器前進後退的,不只能夠支持hash,非hash的同源
url 也支持。

九、HTML5離線緩存

HTML5離線緩存又叫Application
Cache,是從瀏覽器的緩存中分出來的一塊緩存區,若是要在這個緩存中保存數據,可使用一個描述文件(manifest file),列出要下載和緩存的資源。

manifest 文件是簡單的文本文件,它告知瀏覽器被緩存的內容(以及不緩存的內容)。manifest 文件可分爲三個部分:

  • CACHE MANIFEST - 在此標題下列出的文件將在首次下載後進行緩存

  • NETWORK - 在此標題下列出的文件須要與服務器的鏈接,且不會被緩存

  • FALLBACK - 在此標題下列出的文件規定當頁面沒法訪問時的回退頁面(好比 404 頁面)

離線緩存爲應用帶來三個優點:

離線瀏覽 - 用戶可在應用離線時使用它們

速度 - 已緩存資源加載得更快

減小服務器負載 - 瀏覽器將只從服務器下載更新過或更改過的資源。

十、Web語義化 和 SEO

Web語義化是指使用語義恰當的標籤,使頁面有良好的結構,頁面元素有含義,可以讓人和搜索引擎都容易理解。

SEO是指在瞭解搜索引擎天然排名機制的基礎之上,對網站進行內部及外部的調整優化,改進網站在搜索引擎中關鍵詞的天然排名,得到更多的展示量,吸引更多目標客戶點擊訪問網站,從而達到互聯網營銷及品牌建設的目標。

搜索引擎經過爬蟲技術獲取的頁面就是由一堆 html 標籤組成的代碼,人能夠經過可視化的方式來判斷頁面上哪些內容是重點,而機器作不到。
但搜索引擎會根據標籤的含義來判斷內容的權重,所以,在合適的位置使用恰當的標籤,使整個頁面的語義明確,結構清晰,搜索引擎才能正確識別頁面中的重要內容,並予以較高的權值。好比h1~h6這幾個標籤在SEO中的權值很是高,用它們做頁面的標題就是一個簡單的SEO優化。

友情連接:http://mp.weixin.qq.com/s/dHriAqydo97PytYMG3s5yQ

相關文章
相關標籤/搜索