1. JavaScript
1.1. 基礎語法
包括:變量聲明、數據類型、函數、控制語句、內置對象等javascript
1.1.1. 變量聲明
ES5:css
var //普通變量
function //函數
ES6新增:html
let //普通變量
const //常量 -- 聲明的同時初始化,不可從新賦值,不能重複聲明
import //模塊
class //類
1.1.2. 數據類型
-- 類型介紹
ES5:
String、Number、Boolean、Null、Undefined、Object
ES6增:
Symbol
其中,object爲引用,其餘爲基本類型前端
- 基本類型
佔據空間固定,是簡單的數據段,將其存儲在棧(stack)中(按值訪問) 便於提高變量查詢速度
爲了便於操做這類數據,ECMAScript提供了 3 個 基本包裝類型 :Boolean、Number 和 String
- 基本包裝類型
一種特殊的引用類型,每當讀取一個基本類型值的時候,JS內部就會建立一個對應的包裝對象,從而能夠調用一些方法來操做這些數據
- 引用類型
- 因爲其值的大小會改變,因此不能將其存放在棧中,不然會下降變量查詢速度
- 將其存儲在堆(heap)中,存儲在變量處的值是一個指針,指向存儲對象的內存處(按址訪問)
- 能夠爲其添加、改變和刪除屬性和方法;但基本類型不能夠添加屬性和方法
-- 類型判斷
1.1.3. 函數
- 普通函數 -- 直接調用
- 構造函數 -- new 建立對象
- 對象方法 -- 對象調用
1.1.4. 內置對象
- window
- Date
- Array
- JSON
- RegExp
-- 淺複製與深拷貝
- 淺複製
對對象地址的複製,並無開闢新的棧,複製的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另外一個對象的屬性也會改變
- 深拷貝
開闢新的棧,兩個對象對應兩個不一樣的地址,修改一個對象的屬性,不會改變另外一個對象的屬性
方法html5
遞歸
js var china = { nation : '中國', birthplaces:['北京','上海','廣州'], skincolr :'yellow', friends:['sk','ls'] } //深複製,要想達到深複製就須要用遞歸 function deepCopy(o,c){ var c = c || {} for(var i in o){ if(typeof o[i] === 'object'){ //要考慮深複製問題了 if(o[i].constructor === Array){ //這是數組 c[i] =[] }else{ //這是對象 c[i] = {} } deepCopy(o[i],c[i]) }else{ c[i] = o[i] } } return c } var result = {name:'result'} result = deepCopy(china,result) console.dir(result)
java
- JSON
var test ={
name:{
xing:{
first:'張',
second:'李'
},
ming:'老頭'
},
age :40,
friend :['隔壁老王','宋經紀','同事']
}
var result = JSON.parse(JSON.stringify(test))
result.age = 30
result.name.xing.first = '往'
result.friend.push('fdagldf;ghad')
console.dir(test)
console.dir(result)

1.2. 函數原型鏈
JS是一種基於對象的語言,但在ES6 以前是不支持繼承的,爲了具有繼承的能力,Javascript 在 函數對象上創建了原型對象prototype,並以函數對象爲主線,從上至下,在JS內部構建了一條 原型鏈node
Object 是全部對象的祖宗, 任何對象所創建的原型鏈最終都指向了Objectwebpack
簡單來講:
創建了變量查找機制,當訪問一個對象的屬性時,先查找對象自己是否存在,若是不存在就去該對象所在的原型連上去找,直到Object對象爲止,若是都沒有找到該屬性纔會返回undefined。所以,咱們能夠經過原型鏈來實現JS繼承css3
1.3. 函數做用域
變量在聲明它們的函數體以及這個函數體嵌套的任意函數體git
JS中沒有塊級做用域,只有函數做用域
致使JS中出現了變量提高的問題
—— 將變量聲明提高到它所在做用域的最開始的部分
爲了解決變量提高帶來的反作用,ES6新增了let 命令來聲明變量,let 所聲明的變量只在 let 命令所在的代碼塊內有效,因此不存在變量提高問題
1.4. this 指針
this 指針存在於函數中,用以標識函數運行時所處的上下文
- 普通函數
始終指向全局對象window
- 構造函數
指向新建立的對象
- 方法
指向調用該方法的對象
- call、apply 和 bind
方法來改變函數的 this 指向,其中,call 和 apply 主動執行函數,bind通常在事件回調中使用, call 和 apply的區別只是參數的傳遞方式不一樣
1.5. new 操做符
函數的建立有三種方式,即 顯式聲明、匿名定義 和 new Function()
JS將新對象的原型鏈指向了構造函數的原型對象,因而就在新對象和函數對象之間創建了一條原型鏈,經過新對象能夠訪問到函數對象原型prototype中的方法和屬性
1.6. 閉包
具備獨立做用域的靜態執行環境
和函數做用域不一樣的是:
- 閉包的做用域
靜態的,能夠永久保存局部資源
- 函數做用域
只存在於運行時,函數執行結束後當即銷燬
所以,閉包能夠造成一個獨立的執行過程
1.7. 單線程和異步
JavaScript
- 單線程語言,在瀏覽器中,當JS代碼被加載時,瀏覽器會爲其分配一個主線程來執行任務(函數)
主線程會造成一個全局執行環境,執行環境在棧中採用後進先出(LIFO)的順序來執行代碼塊,以保證全部的函數能按照正確的順序被執行
- 執行環境中維護了一個異步隊列(也叫工做線程),並將這些耗時任務放入隊列中進行等待
- 如ajax請求、定時器、事件等
- 這些任務的執行時機並不肯定,只有當主線程的任務執行完成之後,主線程纔會去檢查異步隊列中的任務是否須要開始執行。
- JS中的 setTimeout 和 setInterval 就是典型的異步操做,它們會被放入異步隊列中等待,即便 setTimeout(0)也不會被當即執行,須要等到當前同步任務結束後纔會被執行。
1.8. 異步通訊
瀏覽器專門用來和服務器進行交互的異步通信技術
1.8.1. Ajax
- Ajax是瀏覽器專門用來和服務器進行交互的異步通信技術
- 其核心對象是XMLHttpRequest,經過該對象能夠建立一個Ajax請求
- Ajax請求是一個耗時的異步操做,當請求發出之後,Ajax提供了兩個狀態位來描述請求在不一樣階段的狀態,這兩個狀態位分別是
- readyState
- status
readyState 經過5個狀態碼來描述一個請求的5個階段:
0 - 請求未發送,初始化階段
1 - 請求發送中,服務器還未收到請求
2 - 請求發送成功,服務器已收到請求
3 - 服務器處理完成,開始響應請求,傳輸數據
4 - 客戶端收到請求,並完成了數據下載,生成了響應對象
status
- 1xx(臨時響應)表示臨時響應並須要請求者繼續執行操做的狀態碼。
- 2xx(成功)表示成功處理了請求的狀態碼。
- 200(成功):服務器已成功處理了請求。一般,這表示服務器提供了請求的網頁。
- 3xx(重定向)要完成請求,須要進一步操做。
- 301(永久移動):請求的網頁已永久移動到新位置。
- 302(臨時移動):服務器目前從不一樣位置的網頁響應請求,但請求者應繼續使用原有位置來響應之後的請求。
- 304(未修改):自從上次請求後,請求的網頁未修改過。
- 4xx(請求錯誤)這些狀態碼錶示請求可能出錯,妨礙了服務器的處理。
- 400(錯誤請求):服務器不理解請求的語法。
- 404(未找到):服務器找不到請求的網頁。
- 5xx(服務器錯誤)這些狀態碼錶示服務器在處理請求時發生內部錯誤。
- 500(服務器內部錯誤):服務器遇到錯誤,沒法完成請求。
- 503(服務不可用):服務器目前沒法使用(因爲超載或停機維護)
常見問題:
- timeout 只會影響readyState,而不會影響status,由於超時只會中斷數據傳輸,但不會影響服務器的處理結果。 若是 timeout 設置的不合理,就會致使響應碼status 是200,但 response裏卻沒有數據,這種狀況就是服務器正確響應了請求,但數據的下載被超時中斷了。
HTTP 相關請見:
只容許請求和當前地址同域的服務器資源。但不限制腳本和標籤發送跨域請求,好比script 和 img 標籤,所以能夠利用腳本跨域能力來實現跨域請求,即JSONP 的原理。
JSONP雖然能夠解決跨域問題,但只能是get請求,而且沒有有效的錯誤捕獲機制
爲了解決這個問題,XMLHttpRequest Level2 提出了CORS 模型,即 跨域資源共享, 它不是一個新的API,而是一個標準規範,當瀏覽器發現該請求須要跨域時,就會自動在頭信息中添加一個 Origin字段,用以說明本次請求來自哪一個源。服務器根據這個值,決定是否贊成此次請求。
隨着移動端的快速發展,Web技術的應用場景正在變得愈來愈複雜, 關注點分離 原則在系統設計層面就顯得愈來愈重要,而XMLHttpRequest 是 Ajax 最古老的一個接口,於是不太符合現代化的系統設計理念。所以,瀏覽器提供了一個新的 Ajax 接口,即 Fetch API ,Fetch API 是基於Promise 思想設計的,更符合關注點分離原則。
更多請見:
1.9. 模塊化
模塊加載方案,最主要有 CMD 和 AMD 兩種,分別以commonjs 和 requirejs爲表明
ES6 在語言標準的層面上,實現了模塊化編程,其設計思想是,儘可能靜態化,使得編譯時就能肯定模塊的依賴關係,即編譯時加載
CMD和AMD是在運行時肯定依賴關係,即運行時加載
詳情:
AMD && CMD
ES6 模塊化
每個ES6模塊都是一個包含JS代碼的文件,模塊本質上就是一段腳本,而不是用module關鍵字定義一個模塊,可是模塊與腳本仍是有兩點區別:
- 在ES6模塊中,不管你是否加入「use strict;」語句,默認狀況下模塊都是在嚴格模式下運行。
- 在模塊中你可使用import和export關鍵字。
默認狀況下,你在模塊中的全部聲明相對於模塊而言都是寄存在本地的。若是你但願公開在模塊中聲明的內容,並讓其它模塊加以使用,你必定要導出這些功能。想要導出模塊的功能有不少方法,其中最簡單的方式是添加export關鍵字,能夠導出全部的最外層函數、類以及var、let或const聲明的變量。
es6中 代碼就是模塊,不是一段腳本,因此全部的聲明都被限定在模塊的做用域中,對全部腳本和模塊全局不可見。你須要作的是將組成模塊公共API的聲明所有導出。
webpack
在編譯時計算全部依賴並將全部模塊打包成一個文件,經過網絡一次傳輸全部模塊
減小加載模塊時的網絡往返時間
深刻淺出ES6(模塊):http://www.infoq.com/cn/articles/es6-in-depth-modules
1.10. Node.js
一個基於 Chrome V8 引擎的 JavaScript運行環境
Node.js在服務端的優點是,它採用單線程和異步I/O模型,實現了一個高併發、高性能的運行時環境。相比傳統的多線程模型,Node.js實現簡單,而且能夠減小資源開銷
1.11. ES6
目標是讓JS可以方便的開發企業級大型應用程序
變化
- 新增 let、const 命令 來聲明變量
和var 相比,let聲明的變量不存在變量提高問題,但沒有改變JS弱類型的特色,依然能夠接受任意類型變量的聲明;const
聲明的變量不容許在後續邏輯中改變,提升了JS語法的嚴謹性。
- 新增解構賦值、rest語法、箭頭函數
這些都是爲了讓代碼看起來更簡潔,而包裝的語法糖。
- 新增模塊化
這是JS走向規範比較重要的一步,讓前端更方便的實現工程化。
- 新增類和繼承的概念
配合模塊化,JS也能夠實現高複用、高擴展的系統架構。
- 新增模板字符串功能
高效簡潔,結束拼接字符串的時代。
- 新增Promise對象
解決異步回調多層嵌套的問題
使得本來的多層級的嵌套代碼,變成了鏈式調用 讓代碼更清晰,減小嵌套數
promise
- 容器:裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果
- 對象:從它能夠獲取異步操做的消息
特色
- 對象的狀態不受外界影響
Promise對象表明一個異步操做,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和Rejected(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。
- 一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果
Promise對象的狀態改變,只有兩種可能:從Pending變爲Resolved和從Pending變爲Rejected。
缺點
- 沒法取消Promise
一旦新建它就會當即執行,沒法中途取消
- 若是不設置回調函數,Promise內部拋出的錯誤,不會反應到外部
- 當處於Pending狀態時,沒法得知目前進展到哪個階段(剛剛開始仍是即將完成)
更多:
2. CSS
2.1. CSS 選擇器
- 類選擇器
- 標籤選擇器
- ID選擇器
- 後代選擇器
- 羣組選擇器
- 僞類選擇器(before/after)
- 兄弟選擇器(+~)
- 屬性選擇器等等
2.2. 盒子模型
- 塊級盒子(block)
- 行內盒子(inline-block)
相關屬性
margin、border、padding、content
注意
- 只有普通文檔流中塊級盒子的垂直外邊距纔會發生合併,而行內盒子、浮動盒子或絕對定位之間的外邊距不會合並
根據規範,一個盒子若是沒有上補白(padding-top)和上邊框(border-top),那麼這個盒子的上邊距會和其內部文檔流中的第一個子元素的上邊距重疊
爲父元素增長一個border-top或者padding-top便可解決這個問題
- box-sizing 屬性的設置會影響盒子width和height的計算
更多:
2.3. 浮動佈局
設置元素的 float 屬性,能使該元素脫離普通文檔流
若是子元素所有設置爲浮動,則父元素是塌陷的
- 清除浮動
clear:both,
- BFC
浮動元素的父元素 + overflow:hidden 樣式
- 行內盒子(inline-block)
- table也能夠實現一樣的效果。
2.4. 定位佈局
脫離文檔流:position 值爲 relative/absolute/fixed
- relative
相對定位,它以本身原來的位置進行偏移,偏移後,原來的空間不會被其餘元素佔用
- absolute
絕對定位,它以離本身最近的定位父容器做爲參照進行偏移
經常使用的方式就是設置父容器的poistion:relative
- fixed
固定定位,以瀏覽器窗口爲參照物
PC網頁底部懸停的banner通常均可以經過fixed定位來實現,但fixed屬性在移動端有兼容性問題,所以不推薦使用,可替代的方案是:絕對定位+內部滾動。
更多:
2.5. 彈性佈局
即Flex佈局,定義了flex的容器一個可伸縮容器
- 容器自己會根據容器中的元素動態設置自身大小
- 當Flex容器被應用一個大小時(width和height),將會自動調整容器中的元素適應新大小
- Flex容器也能夠設置伸縮比例和固定寬度,還能夠設置容器中元素的排列方向(橫向和縱向)和是否支持元素的自動換行
容器的屬性
- flex-direction屬性
- flex-wrap屬性
- flex-flow
- justify-content屬性
- align-items屬性
- align-content屬性
項目的屬性
- order屬性
- flex-grow屬性
- flex-shrink屬性
- flex-basis屬性
- flex屬性
- align-self屬性
- 注意,設爲Flex佈局之後,子元素的float、clear和vertical-align屬性將失效。
更多: Flex 佈局
2.6. CSS3 動畫
- 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
對比
- animation 設置動畫效果更靈活更豐富
- transition 只能經過主動改變元素的css值才能觸發動畫效果,而animation一旦被應用,就開始執行動畫
2.7. BFC
BFC---Block Formatting Context
是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面元素
好比:內部滾動就是一個BFC,當一個父容器的overflow-y設置爲auto時,而且子容器的長度大於父容器時,就會出現內部滾動,不管內部的元素怎麼滾動,都不會影響父容器之外的佈局,這個父容器的渲染區域就叫BFC。
特色
- 盒子們自所在的containing block頂部一個接一個垂直排列
- 水平方向上撐滿整個寬度(除非內部盒子本身創建了新的BFC)
- 兩個相鄰的BFC之間的距離由margin決定
- 在同一個BFC內部,兩個垂直方向相鄰的塊級元素的margin會發生「塌陷」
觸發BFC
根元素或其它包含它的元素
- float的值不爲none
- overflow的值不爲visible
- display的值爲inline-block、table-cell、table-caption
- position的值爲absolute或fixed
- flex boxes (元素的display: flex或inline-flex)
應用
- 清除內部浮動
對子元素設置浮動後,父元素會發生高度塌陷,也就是父元素的高度變爲0。解決這個問題,只須要把把父元素變成一個BFC就好了。經常使用的辦法是給父元素設置overflow:hidden
- 垂直margin合併
屬於同一個BFC的兩個相鄰元素的margin會發生重疊 —— 建立 BFC
- 建立自適應兩欄佈局 —— 解決侵佔浮動元素的問題
參考: CSS: 潛藏着的BFC
2.8. Sprite,Iconfont,@font-face
- Sprite圖
爲了減小http請求的次數,通常會將經常使用的小圖標排到一個大圖中,頁面加載時只需請求一次網絡,在css中經過設置background-position來控制顯示所須要的小圖標
- Iconfont
即字體圖標,就是將經常使用的圖標轉化爲字體資源存在文件中,經過在CSS中引用該字體文件,而後能夠直接用控制字體的css屬性來設置圖標的樣式
字體圖標的好處是節省網絡請求、其大小不受屏幕分辨率的影響,而且能夠任意修改圖標的顏色
- @font-face
是CSS3中的一個模塊
經過@font-face能夠定義一種全新的字體,經過css屬性font-family來使用這個字體
3. HTML
3.1. 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
- 提供了瀏覽器顯示屏幕的相關屬性,好比顯示屏幕的寬度和高度,可用寬度和高度。
3.2. DOM 系統
Document Object Model 文檔對象模型,是全部瀏覽器公共遵照的標準
- DOM將HTML和XML文檔映射成一個由不一樣節點組成的樹型結構,俗稱DOM樹
- 其核心對象是document,用於描述DOM樹的狀態和屬性,並提供對應的DOM操做API
3.3. 事件系統
事件是用戶與頁面交互的基礎,到目前爲止,DOM事件從PC端的 鼠標事件(mouse) 發展到了 移動端的 觸摸事件(touch) 和
手勢事件(guesture),touch事件描述了手指在屏幕操做的每個細節,guesture 則是描述多手指操做時更爲複雜的狀況
總結以下:
- 第一根手指放下,觸發 touchstart,除此以外什麼都不會發生
- 手指滑動時,觸發touchmove
- 第二根手指放下,觸發 gesturestart
- 觸發第二根手指的 touchstart
- 當即觸發 gesturechange
- 任意手指移動,持續觸發 gesturechange
- 第二根手指彈起時,觸發 gestureend,之後將不會再觸發 gesturechange
- 觸發第二根手指的 touchend
- 觸發touchstart (多根手指在屏幕上,提起一根,會刷新一次全局touch)
- 彈起第一根手指,觸發 touchend
DOM2.0 模型將事件處理流程分爲三個階段,即 事件捕獲階段 、 事件處理階段 、 事件冒泡階段
- 事件捕獲
當用戶觸發點擊事件後,頂層對象document 就會發出一個事件流,從最外層的DOM節點向目標元素節點傳遞,最終到達目標元素。
- 事件處理
當到達目標元素以後,執行目標元素綁定的處理函數。若是沒有綁定監聽函數,則不作任何處理。
- 事件冒泡
事件流從目標元素開始,向最外層DOM節點傳遞,途中若是有節點綁定了事件處理函數,這些函數就會被執行。
利用事件冒泡原理能夠實現 事件委託
所謂事件委託,就是在父元素上添加事件監聽器,用以監聽和處理子元素的事件,避免重複爲子元素綁定相同的事件
- 方式
當目標元素的事件被觸發之後,這個事件就從目標元素開始,向最外層元素傳遞,最終冒泡到父元素上,父元素再經過event.target獲取到這個目標元素
- 好處
父元素只需綁定一個事件監聽,就能夠對全部子元素的事件進行處理了,從而減小了沒必要要的事件綁定,對頁面性能有必定的提高。
更多: 事件委託和 this
3.4. HTML 解析過程
瀏覽器加載 html 文件之後,渲染引擎會從上往下,一步步來解析HTML標籤
過程以下:
- 請求服務器返回HTML文件
用戶輸入網址,瀏覽器向服務器發出請求,服務器返回html文件;
- 生成dom 樹
渲染引擎開始解析 html 標籤,並將標籤轉化爲DOM節點,生成 DOM樹;
- css文件請求
若是head 標籤中引用了外部css文件,則發出css文件請求,服務器返回該文件,該過程會阻塞後面的解析;
- js 請求
若是引用了外部 js 文件,則發出 js 文件請求,服務器返回後當即執行該腳本,這個過程也會阻塞html的解析;
- 生成渲染樹
引擎開始解析 body 裏面的內容,若是標籤裏引用了css 樣式,就須要解析剛纔下載好的css文件,而後用css來設置標籤的樣式屬性,並生成渲染樹;
- 下載圖片資源
若是 body 中的 img 標籤引用了圖片資源,則當即向服務器發出請求,此時引擎不會等待圖片下載完畢,而是繼續解析後面的標籤;
- 從新渲染
- 服務器返回圖片文件,因爲圖片須要佔用必定的空間,會影響到後面元素的排版,所以引擎須要從新渲染這部份內容;
- 若是此時 js 腳本中運行了 style.display="none",佈局被改變,引擎也須要從新渲染這部分代碼;
- 直到 html 結束標籤爲止,頁面解析完畢。
3.5. 重繪 和 迴流
- 迴流
當渲染樹中的一部分(或所有)由於元素的規模尺寸,佈局,隱藏等改變而須要從新構建
如上面的img文件加載完成後就會引發迴流,每一個頁面至少須要一次迴流,就是在頁面第一次加載的時候
- 重繪
當渲染樹中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,好比 background-color
從上面能夠看出,迴流必將引發重繪,而重繪不必定會引發迴流
會引發重繪和迴流的操做以下:
- 添加、刪除元素(迴流+重繪)
- 隱藏元素,display:none(迴流+重繪),visibility:hidden(只重繪,不迴流)
- 移動元素,好比改變top,left的值,或者移動元素到另一個父元素中。(重繪+迴流)
- 對style的操做(對不一樣的屬性操做,影響不同)
- 還有一種是用戶的操做,好比改變瀏覽器大小,改變瀏覽器的字體大小等(迴流+重繪)
- 另外,transform操做不會引發重繪和迴流,是一種高效率的渲染。這是由於transform屬於合成屬性,對合成屬性進行 transition/animation 動畫時將會建立一個合成層,這使得動畫元素在一個獨立的層中進行渲染,當元素的內容沒有發生改變,就不必進行重繪,瀏覽器會經過從新複合來建立動畫幀。
3.6. 本地存儲
避免取回數據前頁面空白,減小請求服務器次數
- cookie
- 本地存儲最原始的方式
cookie 是存放在本地瀏覽器的一段文本,數據以鍵值對的形式保存,能夠設置過時時間。
- 不適合大量數據的存儲
由於每請求一次頁面,cookie 都會發送給服務器,這使得 cookie速度很慢並且效率也不高。所以cookie的大小被限制爲4k左右(不一樣瀏覽器可能不一樣,分HOST)
- html5 提供了兩種在客戶端存儲數據的新方法:
- localStorage
永久存儲
- sessionStorage
存儲期限僅限於瀏覽器會話(session),即當瀏覽器窗口關閉後,sessionStorage中的數據被清除
都是以key/value的形式來存儲數據
localStorage的存儲空間大約5M左右(不一樣瀏覽器可能不一樣,分 HOST),這個至關於一個5M大小的前端數據庫,相比於cookie,能夠節約帶寬,但localStorage在瀏覽器隱私模式下是不可讀取的,當存儲數據超過了 localStorage 的存儲空間後會拋出異常。
此外,H5還提供了逆天的 websql 和 indexedDB,容許前端以關係型數據庫的方式來存儲本地數據
cookie做用是與服務器交互,做爲HTTP規範的一部分,web storage僅僅爲本地存儲而生
更多:經常使用的 web 客戶端存儲
3.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, 10 Nov 2015 08:45:11 GMT,表示在這個時間點以前,緩存都是有效的。
- 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),發包向服務從新拉取文件
3.8. 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 也支持。
3.9. HTML5離線緩存
HTML5離線緩存又叫Application Cache,是從瀏覽器的緩存中分出來的一塊緩存區,若是要在這個緩存中保存數據,可使用一個描述文件(manifest file),列出要下載和緩存的資源。
manifest 文件是簡單的文本文件,它告知瀏覽器被緩存的內容(以及不緩存的內容)。manifest 文件可分爲三個部分:
- CACHE MANIFEST - 在此標題下列出的文件將在首次下載後進行緩存
- NETWORK - 在此標題下列出的文件須要與服務器的鏈接,且不會被緩存
- FALLBACK - 在此標題下列出的文件規定當頁面沒法訪問時的回退頁面(好比 404 頁面)
離線緩存爲應用帶來三個優點:
- 離線瀏覽 - 用戶可在應用離線時使用它們
- 速度 - 已緩存資源加載得更快
- 減小服務器負載 - 瀏覽器將只從服務器下載更新過或更改過的資源。
參考: