Web前端技術(shù)由 html甘凭、css 和 javascript 三大部分構(gòu)成稀拐,是一個(gè)龐大而復(fù)雜的技術(shù)體系,其復(fù)雜程度不低于任何一門后端語言丹弱。而我們在學(xué)習(xí)它的時(shí)候往往是先從某一個(gè)點(diǎn)切入德撬,然后不斷地接觸和學(xué)習(xí)新的知識點(diǎn),因此對于初學(xué)者很難理清楚整個(gè)體系的脈絡(luò)結(jié)構(gòu)躲胳。本文將對Web前端知識體系進(jìn)行簡單的梳理砰逻,對應(yīng)的每個(gè)知識點(diǎn)點(diǎn)到為止,不作詳細(xì)介紹泛鸟。目的是幫助大家審查自己的知識結(jié)構(gòu)是否完善,如有遺漏或不正確的地方踊东,希望共勉北滥。
JAVASCRIPT 篇
0、基礎(chǔ)語法
Javascript 基礎(chǔ)語法包括:變量聲明闸翅、數(shù)據(jù)類型再芋、函數(shù)、控制語句坚冀、內(nèi)置對象等济赎。
在ES5 中,變量聲明有兩種方式记某,分別是 var 和 function 司训,var 用于聲明普通的變量,接收任意類型液南,function用于聲明函數(shù)壳猜。另外,ES6 新增了 let滑凉、const统扳、import 和 class 等四個(gè)命令,分別用以聲明 普通變量畅姊、靜態(tài)變量咒钟、模塊 和 類 。
JS數(shù)據(jù)類型共有六種若未,分別是 String朱嘴、Number、Boolean陨瘩、Null腕够、Undefined 和 Object 等级乍, 另外,ES6 新增了 Symbol 類型帚湘。其中玫荣,Object 是引用類型,其他的都是原始類型(Primitive Type)大诸。
原始類型也稱為基本類型或簡單類型捅厂,因?yàn)槠湔紦?jù)空間固定,是簡單的數(shù)據(jù)段资柔,為了便于提升變量查詢速度焙贷,將其存儲在棧(stack)中(按值訪問)。為了便于操作這類數(shù)據(jù)贿堰,ECMAScript 提供了 3 個(gè)基本包裝類型:Boolean辙芍、Number 和 String 「耄基本包裝類型是一種特殊的引用類型故硅,每當(dāng)讀取一個(gè)基本類型值的時(shí)候,JS內(nèi)部就會創(chuàng)建一個(gè)對應(yīng)的包裝對象纵搁,從而可以調(diào)用一些方法來操作這些數(shù)據(jù)吃衅。
引用類型由于其值的大小會改變,所以不能將其存放在棧中腾誉,否則會降低變量查詢速度徘层,因此其存儲在堆(heap)中,存儲在變量處的值是一個(gè)指針利职,指向存儲對象的內(nèi)存處(按址訪問)趣效,對于引用類型的值,可以為其添加屬性和方法眼耀,也可以改變和刪除其屬性和方法英支;但基本類型不可以添加屬性和方法。關(guān)于更多介紹請參考:詳解 ECMAScript 數(shù)據(jù)類型
JavaScript 可以通過 typeof 來判斷原始數(shù)據(jù)類型哮伟,但不能判斷引用類型干花,要知道引用類型的具體類型,需要通過 Object 原型上的 toString 方法來判斷楞黄,關(guān)于數(shù)據(jù)類型判斷可以參考:判斷JS數(shù)據(jù)類型的4種方法
在 JavaScript 中池凄,函數(shù)有三種角色,即普通函數(shù)鬼廓、構(gòu)造函數(shù) 和 對象方法肿仑。同一個(gè)函數(shù),調(diào)用方式不同,函數(shù)的作用不一樣尤慰,所扮演的角色也不一樣馏锡。直接調(diào)用時(shí)就是普通函數(shù),通過new創(chuàng)建對象時(shí)就是構(gòu)造函數(shù)伟端,通過對象調(diào)用時(shí)就是方法杯道。
JavaScript 常用的內(nèi)置對象有 Date、Array责蝠、JSON党巾、RegExp 等等,Date 和 Array 使用場景最多霜医,JSON主要用于對象的序列化和反序列化齿拂,還有一個(gè)作用就是實(shí)現(xiàn)對象的深拷貝。RegExp 即正則表達(dá)式肴敛,是處理字符串的利器署海。 關(guān)于更多介紹請參考:數(shù)組常用操作方法總結(jié) , 正則表達(dá)式基礎(chǔ)知識
1医男、函數(shù)原型鏈
JS是一種基于對象的語言背蟆,但在 ES6 之前是不支持繼承的难咕,為了具備繼承的能力窑业,JavaScript 在函數(shù)對象上建立了原型對象 prototype音榜,并以函數(shù)對象為主線搪锣,從上至下休建,在JS內(nèi)部構(gòu)建了一條原型鏈盛杰。原型鏈把一個(gè)個(gè)獨(dú)立的對象聯(lián)系在一起翼闽,Object 則是所有對象的祖宗禽捆, 任何對象所建立的原型鏈最終都指向了 Object笙什,并以 Object 終結(jié)。
簡單來說胚想,就是建立了變量查找機(jī)制琐凭,當(dāng)訪問一個(gè)對象的屬性時(shí),先查找對象本身是否存在浊服,如果不存在就去該對象所在的原型連上去找统屈,直到 Object 對象為止,如果都沒有找到該屬性才會返回 undefined牙躺。因此愁憔,我們可以通過原型鏈來實(shí)現(xiàn)繼承機(jī)制。關(guān)于函數(shù)原型鏈請參考:認(rèn)識原型對象和原型鏈
2孽拷、函數(shù)作用域
函數(shù)作用域就是變量在聲明它們的函數(shù)體以及這個(gè)函數(shù)體嵌套的任意函數(shù)體內(nèi)都是有定義的吨掌。通俗來講就是,在一個(gè)函數(shù)里,有些變量可以訪問膜宋,有些不可以訪問窿侈。那些能訪問的變量所形成的范圍,就是這個(gè)函數(shù)的作用域秋茫。
在 JavaScript 中史简,沒有塊級作用域,只有函數(shù)作用域学辱,也就是說 if乘瓤、while、for 語句不會形成獨(dú)立的作用域策泣。但有一個(gè)特殊情況衙傀,即 with 語句和 catch 語句會形成臨時(shí)作用域,語句執(zhí)行結(jié)束后萨咕,該作用域就會被釋放统抬。關(guān)于函數(shù)作用域請參考:函數(shù)作用域和作用域鏈
3、this 指針
this 指針存在于函數(shù)中危队,用以標(biāo)識函數(shù)運(yùn)行時(shí)所處的上下文聪建。函數(shù)的類型不同,this 指向規(guī)則也不一樣:對于普通函數(shù)茫陆,this 始終指向全局對象window金麸;對于構(gòu)造函數(shù),this則指向新創(chuàng)建的對象簿盅;對于方法挥下,this指向調(diào)用該方法的對象。另外桨醋,F(xiàn)unction 對象也提供了call棚瘟、apply 和 bind 等方法來改變函數(shù)的 this 指向,其中喜最,call 和 apply 主動執(zhí)行函數(shù)偎蘸,bind 一般在事件回調(diào)中使用,而 call 和 apply 的區(qū)別只是參數(shù)的傳遞方式不同瞬内。關(guān)于更多介紹請參考:深入理解 call,apply和 bind
如果往深的去理解迷雪,無論什么函數(shù),this 是否被改變虫蝶, 本質(zhì)上振乏,this 均指向觸發(fā)函數(shù)運(yùn)行時(shí)的那個(gè)對象。而在函數(shù)運(yùn)行時(shí)秉扑,this 的值是不能被改變的慧邮。
4调限、new 操作符
函數(shù)的創(chuàng)建有三種方式,即 顯式聲明误澳、匿名定義 和 new Function() 耻矮。前面提到,JS 中的函數(shù)即可以是函數(shù)忆谓,也可以是方法裆装,還可以是構(gòu)造函數(shù)。
當(dāng)使用 new 來創(chuàng)建對象時(shí)倡缠,該函數(shù)就是構(gòu)造函數(shù)哨免,JS 將新對象的原型鏈指向了構(gòu)造函數(shù)的原型對象,于是就在新對象和函數(shù)對象之間建立了一條原型鏈昙沦,通過新對象可以訪問到函數(shù)對象原型 prototype 中的方法和屬性琢唾。關(guān)于構(gòu)造函數(shù)和 new 操作符請參考:* 深入理解 new 操作符*
5、閉包
閉包不是一個(gè)孤立的概念盾饮,需要從函數(shù)作用域的角度來理解采桃。
每個(gè)函數(shù)都有自己的作用域,如果在一個(gè)函數(shù)里定義了另一個(gè)函數(shù)丘损,那么對應(yīng)的就有兩個(gè)作用域普办,這兩個(gè)作用域就會形成一個(gè)鏈條,俗稱作用域鏈徘钥。本質(zhì)上講衔蹲,作用域鏈?zhǔn)且粋€(gè)自上而下的鏈表, 鏈表的最頂端是內(nèi)部函數(shù)作用域呈础,鏈表的最底端是全局作用域踪危。內(nèi)部函數(shù)有權(quán)訪問整個(gè)作用域鏈上的變量。正常情況下猪落,每當(dāng)一個(gè)函數(shù)執(zhí)行完畢,對應(yīng)的作用域就會從該鏈表上移除畴博,然后銷毀笨忌。
但如果函數(shù) A 把函數(shù) B 作為返回值返回時(shí),情況又不一樣俱病。
首先官疲,函數(shù) A 返回的是函數(shù) B 的引用,也就是說亮隙,B 可能會在其他地方被調(diào)用途凫。上面提到,函數(shù) B 的定義是位于函數(shù) A 內(nèi)部溢吻,因此 A 和 B 會形成一條作用域鏈维费,函數(shù) B 有可能會讀取 A 中的變量 果元。為了保證函數(shù) B 能夠在其他地方正確執(zhí)行,函數(shù) B 所在的這條作用域鏈就不能被破壞犀盟。所以而晒,即使函數(shù) A 執(zhí)行返回后,A 的作用域也不能釋放阅畴,需要一直保存在內(nèi)存中倡怎,以確保函數(shù) B 能夠正常讀取里面的變量。函數(shù) B 具有永久訪問 A 作用域的特權(quán)贱枣,確切說监署,函數(shù) B 就是閉包 。
總而言之纽哥,閉包就是一個(gè)有權(quán)訪問另一個(gè)函數(shù)作用域的函數(shù)钠乏。
6、單線程與事件循環(huán)
JavaScript 是單線程語言昵仅。在瀏覽器中缓熟,當(dāng)JS代碼被加載時(shí),瀏覽器會為其分配一個(gè)主線程來執(zhí)行任務(wù)摔笤,主線程會在棧中創(chuàng)建一個(gè)全局執(zhí)行環(huán)境 (全局作用域)够滑。每當(dāng)有一個(gè)函數(shù)進(jìn)入執(zhí)行流時(shí),就會形成一個(gè)對應(yīng)的執(zhí)行環(huán)境(函數(shù)作用域)吕世,并將該執(zhí)行環(huán)境壓入棧中彰触。每當(dāng)一個(gè)函數(shù)執(zhí)行完畢以后,對應(yīng)的執(zhí)行環(huán)境就會從棧中彈出命辖,然后被銷毀况毅。這就是執(zhí)行環(huán)境棧,執(zhí)行環(huán)境棧的作用就是保證所有的函數(shù)能按照正確的順序被執(zhí)行尔艇。
但在瀏覽器中尔许,有一些任務(wù)是非常耗時(shí)的,比如 ajax請求终娃、定時(shí)器味廊、事件等。為了保證主線程上的任務(wù)不被阻塞棠耕,JavaScript 內(nèi)部維護(hù)了一個(gè)任務(wù)隊(duì)列余佛, 當(dāng)這些耗時(shí)任務(wù)結(jié)束時(shí)(Ajax 請求返回、定時(shí)器超時(shí)窍荧、事件被觸發(fā))辉巡,就將對應(yīng)的回調(diào)函數(shù)插入隊(duì)列中進(jìn)行等待。這些任務(wù)的執(zhí)行時(shí)機(jī)并不確定蕊退,只有當(dāng)所有同步任務(wù)執(zhí)行完畢后郊楣,執(zhí)行環(huán)境棧被清空(棧底的全局執(zhí)行環(huán)境會一直存在憔恳,直到進(jìn)程退出)以后,然后再從任務(wù)隊(duì)列中依次讀取回調(diào)函數(shù)痢甘,并將其壓入執(zhí)行環(huán)境棧中喇嘱。于是,主線程開始執(zhí)行新的同步任務(wù)塞栅,執(zhí)行完畢后再從棧中彈出者铜,棧被清空。
主線程從任務(wù)隊(duì)列中讀取任務(wù)是不斷循環(huán)的放椰,每當(dāng)棧被清空后作烟,主線程就會從任務(wù)隊(duì)列中讀取新的任務(wù)并執(zhí)行,如果沒有新的任務(wù)砾医,就會一直等待拿撩,直到有新的任務(wù)。JavaScript 的這種執(zhí)行機(jī)制就叫做任務(wù)循環(huán)如蚜。因?yàn)槊總€(gè)任務(wù)都由一個(gè)事件所觸發(fā)压恒,所以也叫 “事件循環(huán)”。
7错邦、Ajax 和 跨域技術(shù)
Ajax 是瀏覽器專門用來和服務(wù)器進(jìn)行交互的異步通訊技術(shù)探赫,其核心對象是 XMLHttpRequest,通過該對象可以創(chuàng)建一個(gè) Ajax 請求撬呢。Ajax 請求是一個(gè)耗時(shí)的異步操作伦吠,當(dāng)請求發(fā)出以后,Ajax 提供了兩個(gè)狀態(tài)位來描述請求在不同階段的狀態(tài)魂拦,這兩個(gè)狀態(tài)位分別是 readyState 和 status 毛仪,readyState 通過 5個(gè)狀態(tài)碼來描述一個(gè)請求的 5 個(gè)階段:
- 0 - 請求未發(fā)送,初始化階段
- 1 - 請求發(fā)送中芯勘,服務(wù)器還未收到請求
- 2 - 請求發(fā)送成功箱靴,服務(wù)器已收到請求
- 3 - 服務(wù)器處理完成,開始響應(yīng)請求荷愕,傳輸數(shù)據(jù)
- 4 - 客戶端收到請求衡怀,并完成了數(shù)據(jù)下載,生成了響應(yīng)對象
status 用于描述服務(wù)端對請求處理的情況路翻,200 表示正確響應(yīng)了請求,404 表示服務(wù)器找不到資源茄靠,500 代表服務(wù)器內(nèi)部異常等等茂契。
Ajax 對象還可以設(shè)置一個(gè) timeout 值,代表超時(shí)時(shí)間慨绳。切記:timeout 只會影響 readyState掉冶,而不會影響 status真竖,因?yàn)槌瑫r(shí)只會中斷數(shù)據(jù)傳輸,但不會影響服務(wù)器的處理結(jié)果厌小。 如果 timeout 設(shè)置的不合理恢共,就會導(dǎo)致響應(yīng)碼 status 是 200,但 response里卻沒有數(shù)據(jù)璧亚,這種情況就是服務(wù)器正確響應(yīng)了請求讨韭,但數(shù)據(jù)的下載被超時(shí)中斷了。
為了保證用戶信息的安全癣蟋,瀏覽器引入了同源策略透硝,對腳本請求做了限制,不允許 Ajax 跨域請求服務(wù)器 疯搅,只允許請求和當(dāng)前地址同域的服務(wù)器資源濒生。但不限制 HTML 標(biāo)簽發(fā)送跨域請求,比如 script幔欧、img罪治、a 標(biāo)簽等,因此可以利用標(biāo)簽跨域能力來實(shí)現(xiàn)跨域請求礁蔗,這就是 JSONP 能夠跨域的原理觉义。
JSONP 雖然可以解決跨域問題,但只能發(fā)送 GET 請求瘦麸,并且沒有有效的錯(cuò)誤捕獲機(jī)制 谁撼。為了解決這個(gè)問題,W3C 在 XMLHttpRequest Level2 中提出了 CORS 規(guī)范滋饲,即 “跨域資源共享”厉碟。它不是一個(gè)新的 API,而是一個(gè)標(biāo)準(zhǔn)規(guī)范 屠缭。當(dāng)瀏覽器發(fā)現(xiàn)該請求需要跨域時(shí)箍鼓,就會自動在頭信息中添加一個(gè) Origin 字段,用以說明本次請求來自哪個(gè)源呵曹。服務(wù)器根據(jù)這個(gè)值款咖,決定是否同意這次請求。 關(guān)于 CORS 的詳細(xì)介紹請參考:跨域資源共享 CORS 詳解
隨著移動端的快速發(fā)展奄喂,Web 技術(shù)的應(yīng)用場景正在變得越來越復(fù)雜铐殃,“關(guān)注點(diǎn)分離” 原則在系統(tǒng)設(shè)計(jì)層面就顯得越來越重要,而 XMLHttpRequest 是 Ajax 最古老的一個(gè)接口跨新,因而不太符合現(xiàn)代化的系統(tǒng)設(shè)計(jì)理念富腊。因此,瀏覽器提供了一個(gè)新的 Ajax 接口域帐,即 Fetch赘被,F(xiàn)etch 是基于 ES6 的 Promise 思想設(shè)計(jì)的是整,更符合關(guān)注點(diǎn)分離原則。關(guān)于 Fetch 的更多介紹請參考:傳統(tǒng) Ajax 已死民假,F(xiàn)etch 永生
8浮入、模塊化
歷史上,JavaScript 規(guī)范一直沒有模塊(Module)體系羊异,即無法將一個(gè)大程序拆分成互相依賴的小文件事秀,再用簡單的方法拼裝起來。在 ES6 之前球化,為了實(shí)現(xiàn) JS 模塊化編程秽晚,社區(qū)制定了一些模塊加載方案,最主要有 CMD 和 AMD 兩種筒愚,分別以 commonjs 和 requirejs 為代表赴蝇。ES6 在語言標(biāo)準(zhǔn)的層面上,實(shí)現(xiàn)了模塊化編程巢掺,其設(shè)計(jì)思想是句伶,盡量靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴關(guān)系陆淀,即編譯時(shí)加載考余,而 CMD 和 AMD 是在運(yùn)行時(shí)確定依賴關(guān)系,即運(yùn)行時(shí)加載轧苫。關(guān)于 ES6 模塊化請參考:ES6模塊化
9楚堤、Node.js
Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行環(huán)境,它的運(yùn)行不依賴于瀏覽器作為宿主環(huán)境含懊,而是和服務(wù)端程序一樣可以獨(dú)立的運(yùn)行身冬,這使得 JavaScript 編程第一次從客戶端被帶到了服務(wù)端,Node.js 在服務(wù)端的優(yōu)勢是岔乔,它采用單線程和異步 I/O 模型酥筝,實(shí)現(xiàn)了一個(gè)高并發(fā)、高性能的運(yùn)行時(shí)環(huán)境雏门。相比傳統(tǒng)的多線程模型嘿歌,Node.js 實(shí)現(xiàn)簡單,并且可以減少資源開銷茁影。關(guān)于 Node.js單線程模型請參考:Node.js 事件循環(huán)機(jī)制
10宙帝、ES6
ES6 是 ECMAScript 6.0 的簡寫,即 JavaScript 語言的下一代標(biāo)準(zhǔn)募闲,已經(jīng)在 2015年6月正式發(fā)布了步脓,它的目標(biāo)是讓JS能夠方便的開發(fā)企業(yè)級大型應(yīng)用程序,因此,ES6的一些規(guī)范正在逐漸向Java沪编、C# 等后端語言標(biāo)準(zhǔn)靠近。在 ES6 規(guī)范中年扩,比較重大的變化有以下幾個(gè)方面:
- 新增 let蚁廓、const 命令 來聲明變量,和var 相比厨幻,let 聲明的變量不存在變量提升問題相嵌,但沒有改變JS弱類型的特點(diǎn),依然可以接受任意類型變量的聲明况脆;const 聲明的變量不允許在后續(xù)邏輯中改變饭宾,提高了JS語法的嚴(yán)謹(jǐn)性。
- 新增解構(gòu)賦值格了、rest 語法看铆、箭頭函數(shù)等,這些都是為了讓代碼看起來更簡潔盛末,而包裝的語法糖弹惦。
- 新增模塊化機(jī)制,這是 JavaScript 走向規(guī)范比較重要的一步悄但,讓前端更方便的實(shí)現(xiàn)工程化棠隐。
- 新增類和繼承的概念,配合模塊化檐嚣,JavaScript 也可以實(shí)現(xiàn)高復(fù)用助泽、高擴(kuò)展的系統(tǒng)架構(gòu)。
- 新增模板字符串功能嚎京,高效簡潔嗡贺,結(jié)束拼接字符串的時(shí)代。
- 新增 Promise 機(jī)制挖藏,解決異步回調(diào)多層嵌套的問題暑刃。
CSS 篇
1、CSS選擇器
CSS 選擇器即通過某種規(guī)則來匹配相應(yīng)的標(biāo)簽膜眠,并為其設(shè)置 CSS 樣式岩臣,常用的有類選擇器、標(biāo)簽選擇器宵膨、ID選擇器架谎、后代選擇器、群組選擇器辟躏、偽類選擇器(before/after)谷扣、兄弟選擇器(+~)、屬性選擇器等等。
2会涎、CSS Reset
HTML 標(biāo)簽在不設(shè)置任何樣式的情況下裹匙,也會有一個(gè)默認(rèn)的 CSS 樣式,而不同內(nèi)核瀏覽器對于這個(gè)默認(rèn)值的設(shè)置則不盡相同末秃,這樣可能會導(dǎo)致同一套代碼在不同瀏覽器上的顯示效果不一致概页,而出現(xiàn)兼容性問題。因此练慕,在初始化時(shí)惰匙,需要對常用標(biāo)簽的樣式進(jìn)行初始化,使其默認(rèn)樣式統(tǒng)一铃将,這就是 CSS Reset 项鬼,即 CSS 樣式重置,比如:
*{ margin:0; padding:0; }
就是最簡單 CSS Reset劲阎。 關(guān)于 CSS 重置請參考:Neat.css
3绘盟、盒子布局
盒子模型是CSS比較重要的一個(gè)概念,也是CSS 布局的基石悯仙。 常見的盒子模型有塊級盒子(block)和行內(nèi)盒子(inline-block)奥此,與盒子相關(guān)的幾個(gè)屬性有:margin、border雁比、padding和content 等稚虎,這些屬性的作用是設(shè)置盒子與盒子之間的關(guān)系以及盒子與內(nèi)容之間的關(guān)系,而 box-sizing 屬性會影響盒子大小的計(jì)算方式偎捎。
需要注意的是:
只有普通文檔流中塊級盒子的垂直外邊距才會發(fā)生合并蠢终,而具有 BFC 特性盒子的外邊距不會合并。
4茴她、浮動布局
設(shè)置元素的 float 屬性值為 left 或 right寻拂,就能使該元素脫離普通文檔流,向左或向右浮動丈牢。一般在做宮格布局時(shí)會用到祭钉,如果子元素全部設(shè)置為浮動,則父元素是塌陷的己沛,這時(shí)就需要清除浮動慌核,清除浮動的方法也很多,常用的方法是在元素末尾加空元素設(shè)置 clear: both申尼,更高級一點(diǎn)的就給父容器設(shè)置 before/after 來模擬一個(gè)空元素垮卓,還可以直接設(shè)置 overflow 屬性為 auto/hidden 來清除浮動。除浮動可以實(shí)現(xiàn)宮格布局师幕,行內(nèi)盒子(inline-block) 和 table 也可以實(shí)現(xiàn)同樣的效果粟按。
5、定位布局
設(shè)置元素的 position 屬性值為 relative/absolute/fixed,就可以使該元素脫離文檔流灭将,并以某種參照坐標(biāo)進(jìn)行偏移疼鸟。其中,releave 是相對定位庙曙,它以自己原來的位置進(jìn)行偏移愚臀,偏移后,原來的空間不會被其他元素占用矾利;absolute 是絕對定位,它以離自己最近的定位父容器作為參照進(jìn)行偏移馋袜;為了對某個(gè)元素進(jìn)行定位男旗,常用的方式就是設(shè)置父容器的 poistion:relative,因?yàn)橄鄬Χㄎ辉卦诓辉O(shè)置 top 和 left 值時(shí)欣鳖,不會對元素位置產(chǎn)生影響察皇;fixed 即固定定位,它則以瀏覽器窗口為參照物泽台,PC網(wǎng)頁底部懸停的banner一般都可以通過fixed定位來實(shí)現(xiàn)什荣,但fixed屬性在移動端有兼容性問題,因此不推薦使用怀酷,可替代的方案是:絕對定位+內(nèi)部滾動稻爬。
6、彈性布局
彈性布局即 Flex 布局蜕依,定義了 flex 的容器一個(gè)可伸縮容器桅锄,首先容器本身會根據(jù)容器中的元素動態(tài)設(shè)置自身大小样眠;然后當(dāng)Flex容器被應(yīng)用一個(gè)大小時(shí)(width和height)友瘤,將會自動調(diào)整容器中的元素適應(yīng)新大小。Flex容器也可以設(shè)置伸縮比例和固定寬度檐束,還可以設(shè)置容器中元素的排列方向(橫向和縱向)和是否支持元素的自動換行辫秧。有了這個(gè)神器,做頁面布局的可以方便很多了被丧。注意盟戏,設(shè)為Flex 布局以后,子元素的 float甥桂、clear抓半、inline-block 和 vertical-align 屬性將失效。關(guān)于 flexbox 請參考:圖解CSS3 Flexbox屬性
7格嘁、CSS3 動畫
CSS3 中規(guī)范引入了兩種動畫笛求,分別是 transition 和 animation,transition 可以讓元素的 CSS 屬性值的變化在一段時(shí)間內(nèi)平滑的過渡,形成動畫效果探入,為了使元素的變換更加豐富多彩狡孔,CSS3 還引入了 transfrom 屬性,它可以通過對元素進(jìn)行 平移(translate)蜂嗽、旋轉(zhuǎn)(rotate)苗膝、放大縮小(scale)、傾斜(skew) 等操作植旧,來實(shí)現(xiàn) 2D 和 3D 變換效果政勃。transiton 還有一個(gè)結(jié)束事件 transitionEnd,該事件是在 CSS 完成過渡后觸發(fā)裁赠,但如果過渡在完成之前被移除峰髓,則不會觸發(fā) transitionEnd 。
animation 需要設(shè)置一個(gè) @keyframes完沪,來定義元素以哪種形式進(jìn)行變換域庇, 然后再通過動畫函數(shù)讓這種變換平滑的進(jìn)行,從而達(dá)到動畫效果覆积,動畫可以被設(shè)置為永久循環(huán)演示听皿。設(shè)置 animation-play-state:paused 可以暫停動畫,設(shè)置 animation-fill-mode:forwards 可以讓動畫完成后定格在最后一幀宽档。
另外尉姨,還可以通過JS 監(jiān)聽 animation 的“開始”、“結(jié)束” 和 “重復(fù)播放” 狀態(tài)吗冤,分別對應(yīng)三個(gè)事件啊送,即 animationStart、animationEnd欣孤、animationIteration 馋没。需要注意的是:
當(dāng)播放次數(shù)設(shè)置為1時(shí),不會觸發(fā) animationIteration 降传。
和 transition相比篷朵,animation 設(shè)置動畫效果更靈活更豐富,二者還有一個(gè)區(qū)別是:transition 只能通過主動改變元素的 css 值才能觸發(fā)動畫效果婆排,而 animation 一旦被應(yīng)用声旺,就開始執(zhí)行動畫。
另外段只,HTML5 還新增了一個(gè)動畫API腮猖,即 requestAnimationFrame,它通過JS來調(diào)用赞枕,并按照屏幕的繪制頻率來改變元素的CSS屬性澈缺,從而達(dá)到動畫效果坪创,關(guān)于這個(gè)API的介紹請參考:requestAnimationFrame 知多少?
8姐赡、BFC
BFC 是頁面上的一個(gè)隔離的獨(dú)立容器莱预,容器里面的子元素不會影響到外面元素。比如:內(nèi)部滾動就是一個(gè) BFC项滑,當(dāng)一個(gè)父容器的 overflow-y 設(shè)置為 auto 時(shí)依沮,并且子容器的長度大于父容器時(shí),就會出現(xiàn)內(nèi)部滾動枪狂,無論內(nèi)部的元素怎么滾動危喉,都不會影響父容器以外的布局,這個(gè)父容器的渲染區(qū)域就叫 BFC州疾。滿足下列條件之一就可觸發(fā) BFC:
- 根元素辜限,即 HTML 元素
- float 的值不為 none
- overflow 的值不為 visible
- display 的值為 inline-block、table-cell孝治、table-caption
- position 的值為 absolute 或 fixed
9、Sprite审磁,Iconfont谈飒,font-face
對于大型站點(diǎn),為了減少 http 請求的次數(shù)态蒂,一般會將常用的小圖標(biāo)排到一個(gè)大圖中杭措,頁面加載時(shí)只需請求一次網(wǎng)絡(luò), 然后在 css 中通過設(shè)置 background-position 來控制顯示所需要的小圖標(biāo)钾恢,這就是 Sprite 圖手素。
Iconfont,即字體圖標(biāo)瘩蚪,就是將常用的圖標(biāo)轉(zhuǎn)化為字體資源存在文件中泉懦,通過在 CSS 中引用該字體文件,然后可以直接用控制字體的css屬性來設(shè)置圖標(biāo)的樣式疹瘦,字體圖標(biāo)的好處是節(jié)省網(wǎng)絡(luò)請求崩哩、其大小不受屏幕分辨率的影響,并且可以任意修改圖標(biāo)的顏色言沐。
font-face 是 CSS3 中的一個(gè)模塊邓嘹,通過 font-face 可以定義一種全新的字體,然后就可以通過 css 屬性 font-family 來使用這個(gè)字體了险胰,即使操作系統(tǒng)沒有安裝這種字體汹押,網(wǎng)頁上也會正常顯示出來。
10起便、CSS HACK
早期棚贾,不同內(nèi)核瀏覽器對CSS屬性的解析存在著差異窖维,導(dǎo)致顯示效果不一致,比如 margin 屬性在 ie6 中顯示的距離會比其他瀏覽器中顯示的距離寬 2 倍鸟悴,也就是說 margin-left:20px; 在ie6中距左側(cè)元素的實(shí)際顯示距離是 40px陈辱,而在非 ie6 的瀏覽器上顯示正常。因此细诸,如果要想讓所有瀏覽器中都顯示是 20px 的寬度沛贪,就需要在CSS樣式中加入一些特殊的符號,讓不同的瀏覽器識別不同的符號震贵,以達(dá)到應(yīng)用不同的CSS樣式的目的利赋,這種方式就是 “css hack”, 對于 ie6 中的 margin 應(yīng)用 hack 就會變成這樣:
.el {
margin-left: 20px; ``// 其他
_margin-left: 10px;``// ie6
}
|
兼容各大瀏覽器的 css hack 如下:
.element {
color: #000; ``// W3c標(biāo)準(zhǔn)
[;color:#f00;]; ``// Webkit(Chrome/Safari)
color: #666\9; ``// IE8
*color: #999; ``// IE7
_color: #333; ``// IE6
}
:root .element {color: #0f0\9;} ``// IE9
// Opera
@media all and (-webkit-min-device-pixel-ratio:10000),
not all and (-webkit-min-device-pixel-ratio:0) {
.element {color:#336699;}
}
// Firefox
@-moz-document url-prefix() {
.element {color: #f1f1f1}
}
HTML 篇
1猩系、BOM
BOM 是 Browser Object Model 的縮寫媚送,即瀏覽器對象模型,當(dāng)一個(gè)瀏覽器頁面初始化時(shí)寇甸,會在內(nèi)存創(chuàng)建一個(gè)全局的對象塘偎,用以描述當(dāng)前窗口的屬性和狀態(tài),這個(gè)全局對象被稱為瀏覽器對象模型拿霉,即BOM吟秩。BOM的核心對象就是 window,window 對象也是BOM的頂級對象绽淘,其包含了瀏覽器的六個(gè)核心模塊:
- document - 即文檔對象涵防,渲染引擎在解析HTML代碼時(shí),會為每一個(gè)元素生成對應(yīng)的DOM對象沪铭,由于元素之間有層級關(guān)系壮池,因此整個(gè)HTML代碼解析完以后,會生成一個(gè)由不同節(jié)點(diǎn)組成的樹形結(jié)構(gòu)杀怠,俗稱DOM樹椰憋,document 用于描述DOM樹的狀態(tài)和屬性,并提供了很多操作DOM的API赔退。
- frames - HTML 子框架熏矿,即在瀏覽器里嵌入另一個(gè)窗口,父框架和子框架擁有獨(dú)立的作用域和上下文离钝。
- history - 以棧(FIFO)的形式保存著頁面被訪問的歷史記錄票编,頁面前進(jìn)即入棧,頁面返回即出棧卵渴。
- location - 提供了當(dāng)前窗口中加載的文檔相關(guān)信息以及一些導(dǎo)航功能慧域。
- navigator - 用來描述瀏覽器本身,包括瀏覽器的名稱浪读、版本昔榴、語言辛藻、系統(tǒng)平臺、用戶特性字符串等信息互订。
- screen - 提供了瀏覽器顯示屏幕的相關(guān)屬性吱肌,比如顯示屏幕的寬度和高度,可用寬度和高度仰禽。
2氮墨、DOM 系統(tǒng)
DOM 是 Document Object Model 的縮寫,即 文檔對象模型吐葵,是所有瀏覽器公共遵守的標(biāo)準(zhǔn)规揪,DOM 將HTML和XML文檔映射成一個(gè)由不同節(jié)點(diǎn)組成的樹型結(jié)構(gòu),俗稱DOM樹温峭。其核心對象是document猛铅,用于描述DOM樹的狀態(tài)和屬性,并提供對應(yīng)的DOM操作API凤藏。隨著歷史的發(fā)展奸忽,DOM 被劃分為1級、2級揖庄、3級栗菜,共3個(gè)級別:
- 1級DOM - 在1998年10月份成為W3C的提議,由 DOM 核心與 DOM HTML 兩個(gè)模塊組成抠艾。DOM核心能映射以XML為基礎(chǔ)的文檔結(jié)構(gòu)苛萎,允許獲取和操作文檔的任意部分桨昙。DOM HTML通過添加HTML專用的對象與函數(shù)對DOM核心進(jìn)行了擴(kuò)展检号。
- 2級DOM - 鑒于1級DOM僅以映射文檔結(jié)構(gòu)為目標(biāo),DOM 2級面向更為寬廣蛙酪。通過對原有DOM的擴(kuò)展齐苛,2級DOM通過對象接口增加了對鼠標(biāo)和用戶界面事件(DHTML長期支持鼠標(biāo)與用戶界面事件)、范圍桂塞、遍歷(重復(fù)執(zhí)行DOM文檔)和層疊樣式表(CSS)的支持凹蜂。同時(shí)也對DOM 1的核心進(jìn)行了擴(kuò)展,從而可支持XML命名空間阁危。
- 3級DOM - 通過引入統(tǒng)一方式載入和保存文檔和文檔驗(yàn)證方法對DOM進(jìn)行進(jìn)一步擴(kuò)展玛痊,DOM3包含一個(gè)名為“DOM載入與保存”的新模塊,DOM核心擴(kuò)展后可支持XML1.0的所有內(nèi)容狂打,包括XML Infoset擂煞、 XPath、和XML Base趴乡。
瀏覽器對不同級別DOM的支持情況如下所示:
從圖中可以看出对省,移動端常用的 webkit 內(nèi)核瀏覽器目前只支持 DOM2蝗拿,而不支持 DOM3 。
3蒿涎、事件系統(tǒng)
事件是用戶與頁面交互的基礎(chǔ)哀托,到目前為止,DOM事件從PC端的 鼠標(biāo)事件(mouse) 發(fā)展到了 移動端的 觸摸事件(touch) 和 手勢事件(guesture)劳秋,touch事件描述了手指在屏幕操作的每一個(gè)細(xì)節(jié)仓手,guesture 則是描述多手指操作時(shí)更為復(fù)雜的情況,總結(jié)如下:
- 第一根手指放下俗批,觸發(fā) touchstart俗或,除此之外什么都不會發(fā)生
- 手指滑動時(shí),觸發(fā)touchmove
- 第二根手指放下岁忘,觸發(fā) gesturestart
- 觸發(fā)第二根手指的 touchstart
- 立即觸發(fā) gesturechange
- 任意手指移動辛慰,持續(xù)觸發(fā) gesturechange
- 第二根手指彈起時(shí),觸發(fā) gestureend干像,以后將不會再觸發(fā) gesturechange
- 觸發(fā)第二根手指的 touchend
- 觸發(fā)touchstart (多根手指在屏幕上帅腌,提起一根,會刷新一次全局touch)
- 彈起第一根手指麻汰,觸發(fā) touchend
更多關(guān)于手勢事件的介紹請參考:gesture事件處理復(fù)雜手勢
DOM2.0 模型將事件處理流程分為三個(gè)階段速客,即 事件捕獲階段、事件處理階段五鲫、事件冒泡階段溺职,如圖所示:
- 事件捕獲:當(dāng)用戶觸發(fā)點(diǎn)擊事件后,頂層對象 document 就會發(fā)出一個(gè)事件流位喂,從最外層的 DOM 節(jié)點(diǎn)向目標(biāo)元素節(jié)點(diǎn)傳遞浪耘,最終到達(dá)目標(biāo)元素。
- 事件處理:當(dāng)?shù)竭_(dá)目標(biāo)元素之后塑崖,執(zhí)行目標(biāo)元素綁定的處理函數(shù)七冲。如果沒有綁定監(jiān)聽函數(shù),則不做任何處理规婆。
- 事件冒泡:事件流從目標(biāo)元素開始澜躺,向最外層DOM節(jié)點(diǎn)傳遞,途中如果有節(jié)點(diǎn)綁定了事件處理函數(shù)抒蚜,這些函數(shù)就會被執(zhí)行掘鄙。
利用事件冒泡原理可以實(shí)現(xiàn) “事件委托”。
所謂事件委托嗡髓,就是在父元素上添加事件監(jiān)聽器操漠,用以監(jiān)聽和處理子元素的事件,避免重復(fù)為子元素綁定相同的事件器贩。當(dāng)目標(biāo)元素的事件被觸發(fā)以后颅夺,這個(gè)事件就從目標(biāo)元素開始朋截,向最外層元素傳遞,最終冒泡到父元素上吧黄,父元素再通過 event.target 獲取到這個(gè)目標(biāo)元素部服,這樣做的好處是,父元素只需綁定一個(gè)事件監(jiān)聽拗慨,就可以對所有子元素的事件進(jìn)行處理了廓八,從而減少了不必要的事件綁定,對頁面性能有一定的提升赵抢。
4剧蹂、HTML 渲染流程
渲染引擎一開始會從網(wǎng)絡(luò)層獲取請求文檔的內(nèi)容,內(nèi)容的大小一般限制在 8000 個(gè)塊以內(nèi)烦却。
然后進(jìn)行如下所示的基本流程:
- HTML Parser 解析 HTML 文檔宠叼,并將各標(biāo)記逐個(gè)轉(zhuǎn)化為 DOM 節(jié)點(diǎn),生成 “DOM樹”其爵。
- CSS Parser 解析外部 CSS 文件以及樣式元素中的樣式數(shù)據(jù)冒冬,生成 “CSSOM樹”。
- “DOM樹” 和 “CSSOM樹” 通過 “附著” 將創(chuàng)建另一個(gè)樹結(jié)構(gòu):“渲染樹”摩渺。
- 渲染樹包含多個(gè)帶有視覺屬性(如顏色和尺寸)的矩形简烤,這些矩形的排列順序就是它們將在屏幕上顯示的順序。
- 渲染樹構(gòu)建完畢之后摇幻,進(jìn)入“布局” 處理階段横侦,也就是為每個(gè)節(jié)點(diǎn)分配一個(gè)應(yīng)出現(xiàn)在屏幕上的確切坐標(biāo)。
- 下一個(gè)階段是 “繪制”绰姻,渲染引擎會遍歷渲染樹枉侧,由用戶界面后端層將每個(gè)節(jié)點(diǎn)繪制出來。
需要注意的是:
這是一個(gè)漸進(jìn)的過程龙宏。為達(dá)到更好的用戶體驗(yàn)棵逊,呈現(xiàn)引擎會力求盡快將內(nèi)容顯示在屏幕上伤疙。它不必等到整個(gè) HTML 文檔解析完畢之后银酗,就會開始構(gòu)建呈現(xiàn)樹和設(shè)置布局。在不斷接收和處理來自網(wǎng)絡(luò)的其余內(nèi)容的同時(shí)徒像,呈現(xiàn)引擎會將部分內(nèi)容解析并顯示出來黍特。
5、重繪與回流
當(dāng)渲染樹中的一部分(或全部)因?yàn)樵氐囊?guī)模尺寸锯蛀、布局灭衷、隱藏等改變而需要重新構(gòu)建,就稱為 “回流”旁涤。
當(dāng)渲染樹中的一些元素需要更新屬性翔曲,而這些屬性只是影響元素的外觀迫像,風(fēng)格,而不會影響布局瞳遍,就稱為 “重繪”闻妓。
回流必將引起重繪,而重繪不一定會引起回流掠械。
引起重繪和回流的操作如下:
- 添加由缆、刪除元素(回流+重繪)
- 隱藏元素,display: none(回流+重繪)猾蒂,visibility:hidden(只重繪均唉,不回流)
- 移動元素,比如改變 top肚菠、left 的值舔箭,或者移動元素到另外一個(gè)父元素中。(重繪+回流)
- 對 style 的操作(對不同的屬性操作蚊逢,影響不一樣)
- 還有一種是用戶的操作限嫌,比如改變?yōu)g覽器大小,改變?yōu)g覽器的字體大小等(回流+重繪)
注意問題:
transform 操作不會引起重繪和回流时捌,是一種高效率的渲染怒医。這是因?yàn)閠ransform屬于合成屬性,對合成屬性進(jìn)行transition/animation 動畫時(shí)將會創(chuàng)建一個(gè)合成層奢讨,這使得動畫元素在一個(gè)獨(dú)立的層中進(jìn)行渲染稚叹,當(dāng)元素的內(nèi)容沒有發(fā)生改變,就沒必要進(jìn)行重繪拿诸,瀏覽器會通過重新復(fù)合來創(chuàng)建動畫幀扒袖。
6、本地存儲
本地存儲最原始的方式就是 cookie,cookie 是存放在本地瀏覽器的一段文本亩码,數(shù)據(jù)以鍵值對的形式保存季率,可以設(shè)置過期時(shí)間。 但是 cookie 不適合大量數(shù)據(jù)的存儲描沟,因?yàn)槊空埱笠淮雾撁骒海琧ookie 都會發(fā)送給服務(wù)器,這使得 cookie 速度很慢而且效率也不高吏廉。因此cookie的大小被限制為4k左右(不同瀏覽器可能不同,分HOST)泞遗,如下所示:
- Firefox 和 Safari 允許 cookie 多達(dá) 4097 個(gè)字節(jié),包括名(name)席覆、值(value) 和 等號史辙。
- Opera 允許 cookie 多達(dá) 4096 個(gè)字節(jié),包括:名(name)、值(value) 和 等號聊倔。
- Internet Explorer 允許 cookie 多達(dá)4095個(gè)字節(jié)晦毙,包括:名(name)、值(value) 和 等號耙蔑。
在所有瀏覽器中结序,任何 cookie 大小超過限制都被忽略,且永遠(yuǎn)不會被設(shè)置纵潦。
html5 提供了兩種在客戶端存儲數(shù)據(jù)的新方法:localStorage 和 sessionStorage, 它們都是以 key/value 的形式來存儲數(shù)據(jù)徐鹤,前者是永久存儲,后者的存儲期限僅限于瀏覽器會話(session)邀层,即當(dāng)瀏覽器窗口關(guān)閉后返敬,sessionStorage中的數(shù)據(jù)被清除。
localStorage 的存儲空間大約5M左右(不同瀏覽器可能不同寥院,分 HOST)劲赠,這個(gè)相當(dāng)于一個(gè)5M大小的前端數(shù)據(jù)庫,相比于cookie秸谢,可以節(jié)約帶寬凛澎,但localStorage在瀏覽器隱私模式下是不可讀取的,當(dāng)存儲數(shù)據(jù)超過了localStorage 的存儲空間后會拋出異常估蹄。
此外塑煎,H5還提供了 websql 和 indexedDB,允許前端以關(guān)系型數(shù)據(jù)庫的方式來存儲本地?cái)?shù)據(jù)臭蚁,相對來說最铁,這個(gè)功能目前應(yīng)用的場景比較少,此處不作介紹垮兑。
7冷尉、瀏覽器緩存機(jī)制
瀏覽器緩存機(jī)制是指通過 HTTP 協(xié)議頭里的 Cache-Control (或 Expires) 和 Last-Modified (或 Etag) 等字段來控制文件緩存的機(jī)制。
Cache-Control 用于控制文件在本地緩存有效時(shí)長系枪。最常見的雀哨,比如服務(wù)器回包:Cache-Control:max-age=600 表示文件在本地應(yīng)該緩存,且有效時(shí)長是600秒 (從發(fā)出請求算起)私爷。在接下來600秒內(nèi)雾棺,如果有請求這個(gè)資源,瀏覽器不會發(fā)出 HTTP 請求当犯,而是直接使用本地緩存的文件垢村。
Last-Modified 是標(biāo)識文件在服務(wù)器上的最新更新時(shí)間割疾。下次請求時(shí)嚎卫,如果文件緩存過期,瀏覽器通過 If-Modified-Since 字段帶上這個(gè)時(shí)間,發(fā)送給服務(wù)器拓诸,由服務(wù)器比較時(shí)間戳來判斷文件是否有修改侵佃。如果沒有修改,服務(wù)器返回304告訴瀏覽器繼續(xù)使用緩存奠支;如果有修改馋辈,則返回200,同時(shí)返回最新的文件倍谜。
Cache-Control 通常與 Last-Modified 一起使用迈螟。一個(gè)用于控制緩存有效時(shí)間,一個(gè)在緩存失效后尔崔,向服務(wù)查詢是否有更新答毫。
Cache-Control 還有一個(gè)同功能的字段:Expires。Expires 的值一個(gè)絕對的時(shí)間點(diǎn)季春,如:Expires: Thu, 10 Nov 2015 08:45:11 GMT洗搂,表示在這個(gè)時(shí)間點(diǎn)之前,緩存都是有效的载弄。
Expires 是 HTTP1.0 標(biāo)準(zhǔn)中的字段耘拇,Cache-Control 是 HTTP1.1 標(biāo)準(zhǔn)中新加的字段,功能一樣宇攻,都是控制緩存的有效時(shí)間惫叛。當(dāng)這兩個(gè)字段同時(shí)出現(xiàn)時(shí),Cache-Control 是高優(yōu)化級的逞刷。
Etag 也是和 Last-Modified 一樣挣棕,對文件進(jìn)行標(biāo)識的字段。不同的是亲桥,Etag 的取值是一個(gè)對文件進(jìn)行標(biāo)識的特征字串洛心。在向服務(wù)器查詢文件是否有更新時(shí),瀏覽器通過 If-None-Match 字段把特征字串發(fā)送給服務(wù)器题篷,由服務(wù)器和文件最新特征字串進(jìn)行匹配词身,來判斷文件是否有更新。沒有更新回包304番枚,有更新回包200法严。Etag 和 Last-Modified 可根據(jù)需求使用一個(gè)或兩個(gè)同時(shí)使用。兩個(gè)同時(shí)使用時(shí)葫笼,只要滿足基中一個(gè)條件深啤,就認(rèn)為文件沒有更新。
瀏覽緩存的基本框架如下圖所示:
關(guān)于更多瀏覽器緩存介紹請參考:H5 緩存機(jī)制淺析 移動端 Web 加載性能優(yōu)化**
8路星、History
用戶訪問網(wǎng)頁的歷史記錄通常會被保存在一個(gè)類似于棧的對象中溯街,即 history 對象,點(diǎn)擊返回就出棧,跳下一頁就入棧呈昔。 它提供了以下方法來操作頁面的前進(jìn)和后退:
- window.history.back( ) 返回到上一個(gè)頁面
- window.history.forward( ) 進(jìn)入到下一個(gè)頁面
- window.history.go( [delta] ) 跳轉(zhuǎn)到指定頁面
HTML5 對History Api 進(jìn)行了增強(qiáng)挥等,新增了兩個(gè)Api 和一個(gè)事件,分別是 pushState堤尾、replaceState 和 onpopstate:
- pushState 是往 history 對象里添加一個(gè)新的歷史記錄肝劲。
- replaceState 是替換 history 對象中的當(dāng)前歷史記錄。
- onpopstate 當(dāng)點(diǎn)擊瀏覽器后退按鈕或JS調(diào)用 history.back 都會觸發(fā)該事件郭宝。
onpopstate 和 onhashchange 的區(qū)別:
onhashchange 本來是用來監(jiān)聽hash變化的辞槐,但可以被利用來做客戶端前進(jìn)和后退事件的監(jiān)聽,而 onpopstate 是專門用來監(jiān)聽瀏覽器前進(jìn)后退的粘室,不僅可以支持 hash催蝗,非 hash 的同源 url 也支持。
9育特、HTML5 離線緩存
HTML5離線緩存又叫Application Cache丙号,是從瀏覽器的緩存中分出來的一塊緩存區(qū),如果要在這個(gè)緩存中保存數(shù)據(jù)缰冤,可以使用一個(gè)描述文件(manifest file)犬缨,列出要下載和緩存的資源。
manifest 文件是簡單的文本文件棉浸,它告知瀏覽器被緩存的內(nèi)容(以及不緩存的內(nèi)容)怀薛。manifest 文件可分為三個(gè)部分:
- CACHE MANIFEST - 在此標(biāo)題下列出的文件將在首次下載后進(jìn)行緩存
- NETWORK - 在此標(biāo)題下列出的文件需要與服務(wù)器的連接,且不會被緩存
- FALLBACK - 在此標(biāo)題下列出的文件規(guī)定當(dāng)頁面無法訪問時(shí)的回退頁面(比如 404 頁面)
離線緩存為應(yīng)用帶來三個(gè)優(yōu)勢:
- 離線瀏覽 - 用戶可在應(yīng)用離線時(shí)使用它們
- 速度 - 已緩存資源加載得更快
- 減少服務(wù)器負(fù)載 - 瀏覽器將只從服務(wù)器下載更新過或更改過的資源迷郑。
10枝恋、Web語義化與SEO
Web語義化是指使用語義恰當(dāng)?shù)臉?biāo)簽,使頁面有良好的結(jié)構(gòu)嗡害,頁面元素有含義焚碌,能夠讓人和搜索引擎都容易理解。
SEO是指在了解搜索引擎自然排名機(jī)制的基礎(chǔ)之上霸妹,對網(wǎng)站進(jìn)行內(nèi)部及外部的調(diào)整優(yōu)化十电,改進(jìn)網(wǎng)站在搜索引擎中關(guān)鍵詞的自然排名,獲得更多的展現(xiàn)量叹螟,吸引更多目標(biāo)客戶點(diǎn)擊訪問網(wǎng)站鹃骂,從而達(dá)到互聯(lián)網(wǎng)營銷及品牌建設(shè)的目標(biāo)。
搜索引擎通過爬蟲技術(shù)獲取的頁面就是由一堆 html 標(biāo)簽組成的代碼罢绽,人可以通過可視化的方式來判斷頁面上哪些內(nèi)容是重點(diǎn)畏线,而機(jī)器做不到。 但搜索引擎會根據(jù)標(biāo)簽的含義來判斷內(nèi)容的權(quán)重良价,因此寝殴,在合適的位置使用恰當(dāng)?shù)臉?biāo)簽蒿叠,使整個(gè)頁面的語義明確,結(jié)構(gòu)清晰杯矩,搜索引擎才能正確識別頁面中的重要內(nèi)容栈虚,并予以較高的權(quán)值袖外。比如h1~h6這幾個(gè)標(biāo)簽在SEO中的權(quán)值非常高史隆,用它們作頁面的標(biāo)題就是一個(gè)簡單的SEO優(yōu)化。
轉(zhuǎn)載自一像素