姓名:岳沁? 學號:17101223458
轉(zhuǎn)載自:http://www.cnblogs.com/fsyz/p/8029186.html
【嵌牛導讀】:
【嵌牛鼻子】:git
【嵌牛提問】:使用git還應(yīng)注意哪些問題斗蒋?
【嵌牛正文】:
Web前端技術(shù)由 html捌斧、css 和 javascript 三大部分構(gòu)成,是一個龐大而復(fù)雜的技術(shù)體系泉沾,其復(fù)雜程度不低于任何一門后端語言捞蚂。而我們在學習它的時候往往是先從某一個點切入,然后不斷地接觸和學習新的知識點跷究,因此對于初學者很難理清楚整個體系的脈絡(luò)結(jié)構(gòu)姓迅。本文將對Web前端知識體系進行簡單的梳理,對應(yīng)的每個知識點點到為止,不作詳細介紹队贱。目的是幫助大家審查自己的知識結(jié)構(gòu)是否完善色冀,如有遺漏或不正確的地方潭袱,希望共勉柱嫌。
一、JAVASCRIPT 篇
0屯换、基礎(chǔ)語法
Javascript 基礎(chǔ)語法包括:變量聲明编丘、數(shù)據(jù)類型、函數(shù)彤悔、控制語句嘉抓、內(nèi)置對象等。
在ES5 中晕窑,變量聲明有兩種方式抑片,分別是 ?var 和 function ,var 用于聲明普通的變量杨赤,接收任意類型敞斋,function用于聲明函數(shù)。另外疾牲,ES6 新增了 let植捎、const、import 和 class 等四個命令阳柔,分別用以聲明 普通變量焰枢、靜態(tài)變量、模塊 和 類 舌剂。
JS數(shù)據(jù)類型共有六種济锄,分別是 String、Number霍转、Boolean荐绝、Null、Undefined 和 Object 等谴忧, 另外很泊,ES6新增了 Symbol 類型。其中沾谓,Object 是引用類型委造,其他的都是原始類型(Primitive Type)。
原始類型也稱為基本類型或簡單類型均驶,因為其占據(jù)空間固定昏兆,是簡單的數(shù)據(jù)段,為了便于提升變量查詢速度妇穴,將其存儲在棧(stack)中(按值訪問)爬虱。為了便于操作這類數(shù)據(jù)隶债,ECMAScript 提供了 3 個基本包裝類型:Boolean、Number 和 String 跑筝∷蓝铮基本包裝類型是一種特殊的引用類型,每當讀取一個基本類型值的時候曲梗,JS內(nèi)部就會創(chuàng)建一個對應(yīng)的包裝對象赞警,從而可以調(diào)用一些方法來操作這些數(shù)據(jù)。
引用類型由于其值的大小會改變虏两,所以不能將其存放在棧中愧旦,否則會降低變量查詢速度,因此其存儲在堆(heap)中定罢,存儲在變量處的值是一個指針笤虫,指向存儲對象的內(nèi)存處(按址訪問),對于引用類型的值祖凫,可以為其添加屬性和方法琼蚯,也可以改變和刪除其屬性和方法;但基本類型不可以添加屬性和方法蝙场。
Javascript 可以通過 typeof 來判斷原始數(shù)據(jù)類型凌停,但不能判斷引用類型,要知道引用類型的具體類型售滤,需要通過 Object 原型上的 toString 方法來判斷
JS中的函數(shù)存在著三種角色:普通函數(shù)罚拟、構(gòu)造函數(shù)、對象方法完箩。同一個函數(shù)赐俗,調(diào)用方式不同,函數(shù)的作用不一樣弊知,所扮演的角色也不一樣阻逮。直接調(diào)用時就是普通函數(shù),通過new創(chuàng)建對象時就是構(gòu)造函數(shù)秩彤,通過對象調(diào)用時就是方法叔扼。
JS常用的內(nèi)置對象有window、Date漫雷、Array瓜富、JSON、RegExp 等降盹,window是瀏覽器在執(zhí)行腳本時創(chuàng)建的一個全局對象与柑,主要描述瀏覽器窗口相關(guān)的屬性和狀態(tài),這個后面會講到,Date 和 Array 使用場景最多价捧,JSON主要用于對象的序列化和反序列化丑念,還有一個作用就是實現(xiàn)對象的深拷貝。RegExp 即正則表達式结蟋,是處理字符串的利器脯倚。
1、函數(shù)原型鏈
JS是一種基于對象的語言椎眯,但在ES6 之前是不支持繼承的挠将,為了具備繼承的能力,Javascript 在函數(shù)對象上建立了原型對象 prototype编整,并以函數(shù)對象為主線养筒,從上至下肉康,在JS內(nèi)部構(gòu)建了一條原型鏈尺栖。原型鏈把一個個獨立的對象聯(lián)系在一起擎鸠,Object 則是所有對象的祖宗褥符,?任何對象所建立的原型鏈最終都指向了Object坯约,并以 Object 終結(jié)瞪浸。
簡單來說遇革,就是建立了變量查找機制什燕,當訪問一個對象的屬性時粘勒,先查找對象本身是否存在,如果不存在就去該對象所在的原型連上去找屎即,直到 Object 對象為止庙睡,如果都沒有找到該屬性才會返回 undefined。因此技俐,我們可以通過原型鏈來實現(xiàn)繼承機制乘陪。
2、函數(shù)作用域
函數(shù)作用域就是變量在聲明它們的函數(shù)體以及這個函數(shù)體嵌套的任意函數(shù)體內(nèi)都是有定義的雕擂。通俗來講就是啡邑,在一個函數(shù)里,有些變量可以訪問井赌,有些不可以訪問谤逼。那些能訪問的變量所形成的范圍,就是這個函數(shù)的作用域仇穗。
在 JavaScript 中流部,沒有塊級作用域,只有函數(shù)作用域仪缸,也就是說 if贵涵、while、for 語句不會形成獨立的作用域。但有一個特殊情況宾茂,即 with 語句和 catch 語句會形成臨時作用域瓷马,語句執(zhí)行結(jié)束后,該作用域就會被釋放跨晴。
3欧聘、this 指針
this 指針存在于函數(shù)中,用以標識函數(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ù)的傳遞方式不同。
如果往深的去理解探橱,無論什么函數(shù)申屹,this 是否被改變, 本質(zhì)上走搁,this 均指向觸發(fā)函數(shù)運行時的那個對象独柑。而在函數(shù)運行時,this 的值是不能被改變的私植。
4忌栅、new 操作符
函數(shù)的創(chuàng)建有三種方式,即 顯式聲明曲稼、匿名定義 和 new Function() 索绪。前面提到,JS 中的函數(shù)即可以是函數(shù)贫悄,也可以是方法瑞驱,還可以是構(gòu)造函數(shù)。
當使用new來創(chuàng)建對象時窄坦,該函數(shù)就是構(gòu)造函數(shù)唤反,JS 將新對象的原型鏈指向了構(gòu)造函數(shù)的原型對象凳寺,于是就在新對象和函數(shù)對象之間建立了一條原型鏈,通過新對象可以訪問到函數(shù)對象原型 prototype 中的方法和屬性彤侍。
5肠缨、閉包
閉包不是一個孤立的概念,需要從函數(shù)作用域的角度來理解盏阶。
每個函數(shù)都有自己的作用域晒奕,如果在一個函數(shù)里定義了另一個函數(shù),那么對應(yīng)的就有兩個作用域名斟,這兩個作用域就會形成一個鏈條脑慧,俗稱作用域鏈。本質(zhì)上講砰盐,作用域鏈是一個自上而下的鏈表闷袒, 鏈表的最頂端是內(nèi)部函數(shù)作用域,鏈表的最底端是全局作用域楞卡。內(nèi)部函數(shù)有權(quán)訪問整個作用域鏈上的變量霜运。正常情況下,每當一個函數(shù)執(zhí)行完畢蒋腮,對應(yīng)的作用域就會從該鏈表上移除,然后銷毀藕各。
但如果函數(shù) A 把函數(shù) B 作為返回值返回時池摧,情況又不一樣。
首先激况,函數(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 就是閉包 误续。
6、單線程與事件循環(huán)
Javascript 是單線程語言扫茅。在瀏覽器中蹋嵌,當JS代碼被加載時,瀏覽器會為其分配一個主線程來執(zhí)行任務(wù)诞帐,主線程會在棧中創(chuàng)建一個全局執(zhí)行環(huán)境 (全局作用域)欣尼。每當有一個函數(shù)進入執(zhí)行流時,就會形成一個對應(yīng)的執(zhí)行環(huán)境(函數(shù)作用域)停蕉,并將該執(zhí)行環(huán)境壓入棧中愕鼓。每當一個函數(shù)執(zhí)行完畢以后,對應(yīng)的執(zhí)行環(huán)境就會從棧中彈出慧起,然后被銷毀菇晃。這就是執(zhí)行環(huán)境棧,執(zhí)行環(huán)境棧的作用就是保證所有的函數(shù)能按照正確的順序被執(zhí)行蚓挤。
但在瀏覽器中磺送,有一些任務(wù)是非常耗時的,比如 ajax請求灿意、定時器估灿、事件等。為了保證主線程任務(wù)不受影響缤剧,Javascript 內(nèi)部維護了一個任務(wù)隊列馅袁, 當這些耗時任務(wù)結(jié)束時(Ajax 請求返回、定時器超時荒辕、事件被觸發(fā))汗销,就將對應(yīng)的回調(diào)函數(shù)插入隊列中進行等待。這些任務(wù)的執(zhí)行時機并不確定抵窒,只有當所有同步任務(wù)執(zhí)行完畢后弛针,執(zhí)行環(huán)境棧被清空(棧底的全局執(zhí)行環(huán)境會一直存在,直到進程退出)以后李皇,然后再從任務(wù)隊列中依次讀取回調(diào)函數(shù)削茁,并將其壓入執(zhí)行環(huán)境棧中。于是疙赠,主線程開始執(zhí)行新的同步任務(wù)付材,執(zhí)行完畢后再從棧中彈出,棧被清空圃阳。
主線程從任務(wù)隊列中讀取任務(wù)是不斷循環(huán)的厌衔,每當棧被清空后,主線程就會從任務(wù)隊列中讀取新的任務(wù)并執(zhí)行捍岳,如果沒有新的任務(wù)富寿,就會一直等待睬隶,直到有新的任務(wù)。JavaScript 的這種執(zhí)行機制就叫做任務(wù)循環(huán)页徐。因為每個任務(wù)都由一個事件所觸發(fā)苏潜,所以也叫事件循環(huán)。
7变勇、異步通信 Ajax技術(shù)
Ajax是瀏覽器專門用來和服務(wù)器進行交互的異步通訊技術(shù)恤左,其核心對象是 XMLHttpRequest,通過該對象可以創(chuàng)建一個 Ajax 請求搀绣。Ajax 請求是一個耗時的異步操作飞袋,當請求發(fā)出以后,Ajax 提供了兩個狀態(tài)位來描述請求在不同階段的狀態(tài)链患,這兩個狀態(tài)位分別是 readyState 和 status 巧鸭,readyState 通過 5個狀態(tài)碼來描述一個請求的 5 個階段:
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è)置一個 timeout 值,代表超時時間婉宰。切記:timeout 只會影響 readyState歌豺,而不會影響 status,因為超時只會中斷數(shù)據(jù)傳輸心包,但不會影響服務(wù)器的處理結(jié)果类咧。 如果 timeout 設(shè)置的不合理,就會導致響應(yīng)碼 status 是 200蟹腾,但 response里卻沒有數(shù)據(jù)痕惋,這種情況就是服務(wù)器正確響應(yīng)了請求,但數(shù)據(jù)的下載被超時中斷了娃殖。
為了保證用戶信息的安全值戳,瀏覽器引入了同源策略,對腳本請求做了限制炉爆,不允許 Ajax 跨域請求服務(wù)器 堕虹,只允許請求和當前地址同域的服務(wù)器資源卧晓。但不限制 HTML 標簽發(fā)送跨域請求,比如 script赴捞、img逼裆、a 標簽等,因此可以利用標簽跨域能力來實現(xiàn)跨域請求赦政,這就是 JSONP 能夠跨域的原理胜宇。
JSONP 雖然可以解決跨域問題,但只能發(fā)送 GET 請求恢着,并且沒有有效的錯誤捕獲機制 桐愉。為了解決這個問題,W3C 在 XMLHttpRequest Level2 中提出了 CORS 規(guī)范然评,即 跨域資源共享仅财。它不是一個新的 API,而是一個標準規(guī)范 碗淌。當瀏覽器發(fā)現(xiàn)該請求需要跨域時盏求,就會自動在頭信息中添加一個 Origin 字段,用以說明本次請求來自哪個源亿眠。服務(wù)器根據(jù)這個值碎罚,決定是否同意這次請求。
隨著移動端的快速發(fā)展纳像,Web 技術(shù)的應(yīng)用場景正在變得越來越復(fù)雜荆烈,關(guān)注點分離原則在系統(tǒng)設(shè)計層面就顯得越來越重要,而 XMLHttpRequest 是 Ajax 最古老的一個接口竟趾,因而不太符合現(xiàn)代化的系統(tǒng)設(shè)計理念憔购。因此,瀏覽器提供了一個新的 Ajax 接口岔帽,即?Fetch玫鸟,F(xiàn)etch 是基于 ES6 的 Promise 思想設(shè)計的,更符合關(guān)注點分離原則犀勒。
8屎飘、模塊化
歷史上,Javascript 規(guī)范一直沒有模塊(module)體系贾费,即無法將一個大程序拆分成互相依賴的小文件钦购,再用簡單的方法拼裝起來。在 ES6 之前褂萧,為了實現(xiàn) JS 模塊化編程押桃,社區(qū)制定了一些模塊加載方案,最主要有 CMD 和 AMD 兩種箱玷,分別以 commonjs 和 requirejs 為代表怨规。ES6 在語言標準的層面上陌宿,實現(xiàn)了模塊化編程,其設(shè)計思想是波丰,盡量靜態(tài)化壳坪,使得編譯時就能確定模塊的依賴關(guān)系,即編譯時加載掰烟,而 CMD 和 AMD 是在運行時確定依賴關(guān)系爽蝴,即運行時加載。
9纫骑、Node.js
Node.js?是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境蝎亚,它的運行不依賴于瀏覽器作為宿主環(huán)境,而是和服務(wù)端程序一樣可以獨立的運行先馆,這使得JS編程第一次從客戶端被帶到了服務(wù)端发框,Node.js 在服務(wù)端的優(yōu)勢是,它采用單線程和異步I/O模型煤墙,實現(xiàn)了一個高并發(fā)梅惯、高性能的運行時環(huán)境。相比傳統(tǒng)的多線程模型仿野,Node.js 實現(xiàn)簡單铣减,并且可以減少資源開銷。
10脚作、ES6
ES6 是?ECMAScript 6.0 的簡寫葫哗,即 Javascript 語言的下一代標準,已經(jīng)在 2015年6月正式發(fā)布了球涛,它的目標是讓JS能夠方便的開發(fā)企業(yè)級大型應(yīng)用程序劣针,因此,ES6的一些規(guī)范正在逐漸向Java亿扁、C# 等后端語言標準靠近酿秸。ES6 規(guī)范中,比較重大的變化有以下幾個方面:
新增 let魏烫、const 命令 來聲明變量,和var 相比肝箱,let 聲明的變量不存在變量提升問題哄褒,但沒有改變JS弱類型的特點,依然可以接受任意類型變量的聲明煌张;const 聲明的變量不允許在后續(xù)邏輯中改變呐赡,提高了JS語法的嚴謹性。
新增解構(gòu)賦值骏融、rest語法链嘀、箭頭函數(shù)等萌狂,這些都是為了讓代碼看起來更簡潔,而包裝的語法糖怀泊。
新增模塊化機制茫藏,這是 JavaScript 走向規(guī)范比較重要的一步,讓前端更方便的實現(xiàn)工程化霹琼。
新增類和繼承的概念务傲,配合模塊化,JavaScript 也可以實現(xiàn)高復(fù)用枣申、高擴展的系統(tǒng)架構(gòu)售葡。
新增模板字符串功能,高效簡潔忠藤,結(jié)束拼接字符串的時代挟伙。
新增 Promise 機制,解決異步回調(diào)多層嵌套的問題模孩。
二尖阔、CSS 篇
1、CSS選擇器
CSS選擇器即通過某種規(guī)則來匹配相應(yīng)的標簽瓜贾,并為其設(shè)置CSS樣式诺祸,常用的有類選擇器、標簽選擇器祭芦、ID選擇器筷笨、后代選擇器、群組選擇器龟劲、偽類選擇器(before/after)胃夏、兄弟選擇器(+~)、屬性選擇器等等昌跌。
2仰禀、CSS Reset
HTML 標簽在不設(shè)置任何樣式的情況下,也會有一個默認的CSS樣式蚕愤,而不同內(nèi)核瀏覽器對于這個默認值的設(shè)置則不盡相同答恶,這樣可能會導致同一套代碼在不同瀏覽器上的顯示效果不一致,而出現(xiàn)兼容性問題萍诱。因此悬嗓,在初始化時,需要對常用標簽的樣式進行初始化裕坊,使其默認樣式統(tǒng)一包竹,這就是CSS Reset ,即CSS樣式重置,比如:*{margin:0,padding:0} 就是最簡單CSS Reset
3周瞎、盒子布局
盒子模型是CSS比較重要的一個概念苗缩,也是CSS 布局的基石。 常見的盒子模型有塊級盒子(block)和行內(nèi)盒子(inline-block)声诸,與盒子相關(guān)的幾個屬性有:margin酱讶、border、padding和content 等双絮,這些屬性的作用是設(shè)置盒子與盒子之間的關(guān)系以及盒子與內(nèi)容之間的關(guān)系浴麻。其中,只有普通文檔流中塊級盒子的垂直外邊距才會發(fā)生合并囤攀,而行內(nèi)盒子软免、浮動盒子或絕對定位之間的外邊距不會合并。另外焚挠,box-sizing 屬性的設(shè)置會影響盒子width和height的計算膏萧。
4、浮動布局
設(shè)置元素的 float 屬性值為 left 或 right蝌衔,就能使該元素脫離普通文檔流榛泛,向左或向右浮動。一般在做宮格布局時會用到噩斟,如果子元素全部設(shè)置為浮動曹锨,則父元素是塌陷的,這時就需要清除浮動剃允,清除浮動的方法也很多沛简,常用的方法是在元素末尾加空元素設(shè)置clear:both, 更高級一點的就給父容器設(shè)置before/after來模擬一個空元素斥废,還可以直接設(shè)置overflow屬性為auto/hidden來清除浮動椒楣。除浮動可以實現(xiàn)宮格布局,行內(nèi)盒子(inline-block)和table也可以實現(xiàn)同樣的效果牡肉。
5捧灰、定位布局
設(shè)置元素的position屬性值為 relative/absolute/fixed,就可以使該元素脫離文檔流统锤,并以某種參照坐標進行偏移毛俏。其中,releave 是相對定位饲窿,它以自己原來的位置進行偏移拧抖,偏移后,原來的空間不會被其他元素占用免绿;absolute 是絕對定位,它以離自己最近的定位父容器作為參照進行偏移擦盾;為了對某個元素進行定位嘲驾,常用的方式就是設(shè)置父容器的poistion:relative淌哟,因為相對定位元素在不設(shè)置 top 和 left 值時,不會對元素位置產(chǎn)生影響辽故;fixed 即固定定位徒仓,它則以瀏覽器窗口為參照物,PC網(wǎng)頁底部懸停的banner一般都可以通過fixed定位來實現(xiàn)誊垢,但fixed屬性在移動端有兼容性問題掉弛,因此不推薦使用,可替代的方案是:絕對定位+內(nèi)部滾動喂走。
6殃饿、彈性布局
彈性布局即Flex布局,定義了flex的容器一個可伸縮容器芋肠,首先容器本身會根據(jù)容器中的元素動態(tài)設(shè)置自身大泻醴肌;然后當Flex容器被應(yīng)用一個大小時(width和height)帖池,將會自動調(diào)整容器中的元素適應(yīng)新大小奈惑。Flex容器也可以設(shè)置伸縮比例和固定寬度,還可以設(shè)置容器中元素的排列方向(橫向和縱向)和是否支持元素的自動換行睡汹。有了這個神器肴甸,做頁面布局的可以方便很多了。注意囚巴,設(shè)為Flex布局以后原在,子元素的float、clear和vertical-align 屬性將失效文兢。
7晤斩、CSS3 動畫
CSS3中規(guī)范引入了兩種動畫,分別是 transition 和 animation姆坚,transition 可以讓元素的CSS屬性值的變化在一段時間內(nèi)平滑的過渡澳泵,形成動畫效果,為了使元素的變換更加豐富多彩兼呵,CSS3還引入了transfrom 屬性兔辅,它可以通過對元素進行 平移(translate)、旋轉(zhuǎn)(rotate)击喂、放大縮小(scale)维苔、傾斜(skew) 等操作,來實現(xiàn)2D和3D變換效果懂昂。transiton 還有一個結(jié)束事件 transitionEnd介时,該事件是在CSS完成過渡后觸發(fā),如果過渡在完成之前被移除,則不會觸發(fā)transitionEnd 沸柔。
animation 需要設(shè)置一個@keyframes循衰,來定義元素以哪種形式進行變換, 然后再通過動畫函數(shù)讓這種變換平滑的進行褐澎,從而達到動畫效果会钝,動畫可以被設(shè)置為永久循環(huán)演示。設(shè)置?animation-play-state:paused 可以暫停動畫工三,設(shè)置?animation-fill-mode:forwards 可以讓動畫完成后定格在最后一幀迁酸。另外,還可以通過JS監(jiān)聽animation的開始俭正、結(jié)束和重復(fù)播放時的狀態(tài)奸鬓,分別對應(yīng)三個事件,即 animationStart段审、animationEnd删窒、animationIteration 篓叶。注意双吆,當播放次數(shù)設(shè)置為1時胳搞,不會觸發(fā) animationIteration 。
和 transition相比姥闪,animation 設(shè)置動畫效果更靈活更豐富始苇,還有一個區(qū)別是:transition 只能通過主動改變元素的css值才能觸發(fā)動畫效果,而animation一旦被應(yīng)用筐喳,就開始執(zhí)行動畫催式。另外,HTML5 還新增了一個動畫API避归,即 requestAnimationFrame荣月,它通過JS來調(diào)用,并按照屏幕的繪制頻率來改變元素的CSS屬性梳毙,從而達到動畫效果哺窄,e
8、BFC
BFC是頁面上的一個隔離的獨立容器账锹,容器里面的子元素不會影響到外面元素萌业。比如:內(nèi)部滾動就是一個BFC,當一個父容器的overflow-y設(shè)置為auto時奸柬,并且子容器的長度大于父容器時生年,就會出現(xiàn)內(nèi)部滾動,無論內(nèi)部的元素怎么滾動廓奕,都不會影響父容器以外的布局抱婉,這個父容器的渲染區(qū)域就叫BFC档叔。滿足下列條件之一就可觸發(fā)BFC:
根元素,即HTML元素
float的值不為none
overflow的值不為visible
display的值為inline-block蒸绩、table-cell蹲蒲、table-caption
position的值為absolute或fixed
9、Sprite侵贵,Iconfont,@font-face
對于大型站點缘薛,為了減少http請求的次數(shù)窍育,一般會將常用的小圖標排到一個大圖中,頁面加載時只需請求一次網(wǎng)絡(luò)宴胧, 然后在css中通過設(shè)置background-position來控制顯示所需要的小圖標漱抓,這就是Sprite圖。
Iconfont恕齐,即字體圖標乞娄,就是將常用的圖標轉(zhuǎn)化為字體資源存在文件中,通過在CSS中引用該字體文件显歧,然后可以直接用控制字體的css屬性來設(shè)置圖標的樣式仪或,字體圖標的好處是節(jié)省網(wǎng)絡(luò)請求、其大小不受屏幕分辨率的影響士骤,并且可以任意修改圖標的顏色范删。
@font-face是CSS3中的一個模塊,通過@font-face可以定義一種全新的字體拷肌,然后就可以通過css屬性font-family來使用這個字體了到旦,即使操作系統(tǒng)沒有安裝這種字體,網(wǎng)頁上也會正常顯示出來巨缘。
10添忘、CSS Hack
早期,不同內(nèi)核瀏覽器對CSS屬性的解析存在著差異若锁,導致顯示效果不一致搁骑,比如 margin 屬性在ie6中顯示的距離會比其他瀏覽器中顯示的距離寬2倍,也就是說margin-left:20px;在ie6中距左側(cè)元素的實際顯示距離是40px拴清,而在非ie6的瀏覽器上顯示正常靶病。因此,如果要想讓所有瀏覽器中都顯示是20px的寬度口予,就需要在CSS樣式中加入一些特殊的符號娄周,讓不同的瀏覽器識別不同的符號,以達到應(yīng)用不同的CSS樣式的目的沪停,這種方式就是css hack煤辨, 對于ie6中的margin應(yīng)用hack就會變成這樣:.el {margin-left:20px;_margin-left:10px}
兼容各大瀏覽器的 css hack 如下:
三裳涛、HTML 篇
1、BOM
BOM 是?Browser Object Model 的縮寫众辨,即瀏覽器對象模型端三,當一個瀏覽器頁面初始化時,會在內(nèi)存創(chuàng)建一個全局的對象鹃彻,用以描述當前窗口的屬性和狀態(tài)郊闯,這個全局對象被稱為瀏覽器對象模型,即BOM蛛株。BOM的核心對象就是window团赁,window 對象也是BOM的頂級對象,其中包含了瀏覽器的 6個核心模塊:
document- 即文檔對象谨履,渲染引擎在解析HTML代碼時欢摄,會為每一個元素生成對應(yīng)的DOM對象,由于元素之間有層級關(guān)系笋粟,因此整個HTML代碼解析完以后怀挠,會生成一個由不同節(jié)點組成的樹形結(jié)構(gòu),俗稱DOM樹害捕,document 用于描述DOM樹的狀態(tài)和屬性绿淋,并提供了很多操作DOM的API。
frames- HTML 子框架吨艇,即在瀏覽器里嵌入另一個窗口躬它,父框架和子框架擁有獨立的作用域和上下文。
history- 以棧(FIFO)的形式保存著頁面被訪問的歷史記錄东涡,頁面前進即入棧冯吓,頁面返回即出棧。
location-?提供了當前窗口中加載的文檔相關(guān)信息以及一些導航功能疮跑。
navigator-?用來描述瀏覽器本身组贺,包括瀏覽器的名稱、版本祖娘、語言失尖、系統(tǒng)平臺、用戶特性字符串等信息渐苏。
screen- 提供了瀏覽器顯示屏幕的相關(guān)屬性掀潮,比如顯示屏幕的寬度和高度,可用寬度和高度琼富。
2仪吧、DOM 系統(tǒng)
DOM 是 Document Object Model 的縮寫,即 文檔對象模型鞠眉,是所有瀏覽器公共遵守的標準薯鼠,DOM 將HTML和XML文檔映射成一個由不同節(jié)點組成的樹型結(jié)構(gòu)择诈,俗稱DOM樹。其核心對象是document出皇,用于描述DOM樹的狀態(tài)和屬性羞芍,并提供對應(yīng)的DOM操作API。隨著歷史的發(fā)展郊艘,DOM 被劃分為1級荷科、2級、3級纱注,共3個級別:
1級DOM- 在1998年10月份成為W3C的提議步做,由DOM核心與DOM HTML兩個模塊組成。DOM核心能映射以XML為基礎(chǔ)的文檔結(jié)構(gòu)奈附,允許獲取和操作文檔的任意部分。DOM HTML通過添加HTML專用的對象與函數(shù)對DOM核心進行了擴展煮剧。
2級DOM- 鑒于1級DOM僅以映射文檔結(jié)構(gòu)為目標斥滤,DOM 2級面向更為寬廣。通過對原有DOM的擴展勉盅,2級DOM通過對象接口增加了對鼠標和用戶界面事件(DHTML長期支持鼠標與用戶界面事件)佑颇、范圍、遍歷(重復(fù)執(zhí)行DOM文檔)和層疊樣式表(CSS)的支持草娜。同時也對DOM 1的核心進行了擴展挑胸,從而可支持XML命名空間。
3級DOM-?通過引入統(tǒng)一方式載入和保存文檔和文檔驗證方法對DOM進行進一步擴展宰闰,DOM3包含一個名為“DOM載入與保存”的新模塊茬贵,DOM核心擴展后可支持XML1.0的所有內(nèi)容,包括XML Infoset移袍、 XPath解藻、和XML Base。
瀏覽器對不同級別DOM的支持情況如下所示:
從圖中可以看出葡盗,移動端常用的 webkit 內(nèi)核瀏覽器目前只支持 DOM2螟左,而不支持 DOM3 。
3觅够、事件系統(tǒng)
事件是用戶與頁面交互的基礎(chǔ)胶背,到目前為止,DOM事件從PC端的 鼠標事件(mouse) 發(fā)展到了 移動端的 觸摸事件(touch) 和 手勢事件(guesture)喘先,touch事件描述了手指在屏幕操作的每一個細節(jié)钳吟,guesture 則是描述多手指操作時更為復(fù)雜的情況,總結(jié)如下:
第一根手指放下苹祟,觸發(fā) touchstart砸抛,除此之外什么都不會發(fā)生
手指滑動時评雌,觸發(fā)touchmove
第二根手指放下,觸發(fā) gesturestart
觸發(fā)第二根手指的 touchstart
立即觸發(fā)?gesturechange
任意手指移動直焙,持續(xù)觸發(fā) gesturechange
第二根手指彈起時景东,觸發(fā) gestureend,以后將不會再觸發(fā) gesturechange
觸發(fā)第二根手指的 touchend
觸發(fā)touchstart (多根手指在屏幕上奔誓,提起一根斤吐,會刷新一次全局touch)
彈起第一根手指,觸發(fā) touchend
DOM2.0 模型將事件處理流程分為三個階段厨喂,即事件捕獲階段和措、事件處理階段、事件冒泡階段蜕煌,如圖所示:
事件捕獲:當用戶觸發(fā)點擊事件后派阱,頂層對象document 就會發(fā)出一個事件流,從最外層的DOM節(jié)點向目標元素節(jié)點傳遞斜纪,最終到達目標元素贫母。
事件處理:當?shù)竭_目標元素之后,執(zhí)行目標元素綁定的處理函數(shù)盒刚。如果沒有綁定監(jiān)聽函數(shù)腺劣,則不做任何處理。
事件冒泡:事件流從目標元素開始因块,向最外層DOM節(jié)點傳遞橘原,途中如果有節(jié)點綁定了事件處理函數(shù),這些函數(shù)就會被執(zhí)行涡上。
利用事件冒泡原理可以實現(xiàn)事件委托趾断,所謂事件委托,就是在父元素上添加事件監(jiān)聽器吩愧,用以監(jiān)聽和處理子元素的事件歼冰,避免重復(fù)為子元素綁定相同的事件。當目標元素的事件被觸發(fā)以后耻警,這個事件就從目標元素開始隔嫡,向最外層元素傳遞,最終冒泡到父元素上甘穿,父元素再通過event.target 獲取到這個目標元素腮恩,這樣做的好處是,父元素只需綁定一個事件監(jiān)聽温兼,就可以對所有子元素的事件進行處理了秸滴,從而減少了不必要的事件綁定,對頁面性能有一定的提升募判。
4荡含、HTML解析過程
瀏覽器加載 html 文件以后咒唆,渲染引擎會從上往下,一步步來解析HTML標簽释液,大致過程如下:
用戶輸入網(wǎng)址全释,瀏覽器向服務(wù)器發(fā)出請求,服務(wù)器返回html文件误债;
渲染引擎開始解析 html 標簽浸船,并將標簽轉(zhuǎn)化為DOM節(jié)點寝蹈,生成 DOM樹封字;
如果head 標簽中引用了外部css文件,則發(fā)出css文件請求周叮,服務(wù)器返回該文件,該過程會阻塞后面的解析界斜;
如果引用了外部 js 文件峭判,則發(fā)出 js 文件請求疗认,服務(wù)器返回后立即執(zhí)行該腳本横漏,這個過程也會阻塞html的解析二蓝;
引擎開始解析 body 里面的內(nèi)容,如果標簽里引用了css 樣式蓖捶,就需要解析剛才下載好的css文件,然后用css來設(shè)置標簽的樣式屬性犀填,并生成渲染樹;
如果 body 中的 img 標簽引用了圖片資源偿洁,則立即向服務(wù)器發(fā)出請求藻三,此時引擎不會等待圖片下載完畢洪橘,而是繼續(xù)解析后面的標簽;
服務(wù)器返回圖片文件棵帽,由于圖片需要占用一定的空間熄求,會影響到后面元素的排版,因此引擎需要重新渲染這部分內(nèi)容逗概;
如果此時 js 腳本中運行了 style.display="none"弟晚,布局被改變,引擎也需要重新渲染這部分代碼逾苫;
直到 html 結(jié)束標簽為止卿城,頁面解析完畢。
5铅搓、重繪與回流
當渲染樹中的一部分(或全部)因為元素的規(guī)模尺寸瑟押,布局,隱藏等改變而需要重新構(gòu)建星掰。這就稱為回流多望。比如上面的img文件加載完成后就會引起回流,每個頁面至少需要一次回流蹋偏,就是在頁面第一次加載的時候。
當渲染樹中的一些元素需要更新屬性至壤,而這些屬性只是影響元素的外觀威始,風格,而不會影響布局的像街,比如 background-color黎棠。則就叫稱為重繪。
從上面可以看出镰绎,回流必將引起重繪脓斩,而重繪不一定會引起回流。會引起重繪和回流的操作如下:
添加畴栖、刪除元素(回流+重繪)
隱藏元素随静,display:none(回流+重繪),visibility:hidden(只重繪,不回流)
移動元素燎猛,比如改變top,left的值恋捆,或者移動元素到另外一個父元素中。(重繪+回流)
對style的操作(對不同的屬性操作重绷,影響不一樣)
還有一種是用戶的操作沸停,比如改變?yōu)g覽器大小,改變?yōu)g覽器的字體大小等(回流+重繪)
另外昭卓,transform 操作不會引起重繪和回流愤钾,是一種高效率的渲染。這是因為transform屬于合成屬性候醒,對合成屬性進行transition/animation 動畫時將會創(chuàng)建一個合成層能颁,這使得動畫元素在一個獨立的層中進行渲染,當元素的內(nèi)容沒有發(fā)生改變火焰,就沒必要進行重繪劲装,瀏覽器會通過重新復(fù)合來創(chuàng)建動畫幀。
6昌简、本地存儲
本地存儲最原始的方式就是 cookie,cookie 是存放在本地瀏覽器的一段文本占业,數(shù)據(jù)以鍵值對的形式保存,可以設(shè)置過期時間纯赎。 但是 cookie 不適合大量數(shù)據(jù)的存儲谦疾,因為每請求一次頁面,cookie 都會發(fā)送給服務(wù)器犬金,這使得 cookie 速度很慢而且效率也不高念恍。因此cookie的大小被限制為4k左右(不同瀏覽器可能不同,分HOST),如下所示:
Firefox和Safari允許cookie多達4097個字節(jié)晚顷,包括名(name)峰伙、值(value) 和 等號。
Opera允許cookie多達4096個字節(jié)该默,包括:名(name)瞳氓、值(value)?和 等號。
Internet Explorer允許cookie多達4095個字節(jié)栓袖,包括:名(name)匣摘、值(value)?和 等號。
在所有瀏覽器中裹刮,任何cookie大小超過限制都被忽略音榜,且永遠不會被設(shè)置。
html5 提供了兩種在客戶端存儲數(shù)據(jù)的新方法:localStorage 和 sessionStorage, 它們都是以key/value 的形式來存儲數(shù)據(jù)捧弃,前者是永久存儲赠叼,后者的存儲期限僅限于瀏覽器會話(session),即當瀏覽器窗口關(guān)閉后,sessionStorage中的數(shù)據(jù)被清除梅割。
localStorage的存儲空間大約5M左右(不同瀏覽器可能不同霜第,分 HOST),這個相當于一個5M大小的前端數(shù)據(jù)庫户辞,相比于cookie泌类,可以節(jié)約帶寬,但localStorage在瀏覽器隱私模式下是不可讀取的底燎,當存儲數(shù)據(jù)超過了localStorage 的存儲空間后會拋出異常刃榨。
此外,H5還提供了逆天的websql和 indexedDB双仍,允許前端以關(guān)系型數(shù)據(jù)庫的方式來存儲本地數(shù)據(jù)枢希,相對來說,這個功能目前應(yīng)用的場景比較少朱沃,此處不作介紹苞轿。
7、瀏覽器緩存機制
瀏覽器緩存機制是指通過 HTTP 協(xié)議頭里的 Cache-Control (或 Expires) 和 Last-Modified (或 Etag) 等字段來控制文件緩存的機制逗物。
Cache-Control 用于控制文件在本地緩存有效時長搬卒。最常見的,比如服務(wù)器回包:Cache-Control:max-age=600 表示文件在本地應(yīng)該緩存翎卓,且有效時長是600秒 (從發(fā)出請求算起)契邀。在接下來600秒內(nèi),如果有請求這個資源失暴,瀏覽器不會發(fā)出 HTTP 請求坯门,而是直接使用本地緩存的文件。
Last-Modified 是標識文件在服務(wù)器上的最新更新時間逗扒。下次請求時古戴,如果文件緩存過期,瀏覽器通過 If-Modified-Since 字段帶上這個時間矩肩,發(fā)送給服務(wù)器现恼,由服務(wù)器比較時間戳來判斷文件是否有修改。如果沒有修改蛮拔,服務(wù)器返回304告訴瀏覽器繼續(xù)使用緩存述暂;如果有修改痹升,則返回200建炫,同時返回最新的文件。
Cache-Control 通常與 Last-Modified 一起使用疼蛾。一個用于控制緩存有效時間肛跌,一個在緩存失效后,向服務(wù)查詢是否有更新。
Cache-Control 還有一個同功能的字段:Expires衍慎。Expires 的值一個絕對的時間點转唉,如:Expires: Thu, 10 Nov 2015 08:45:11 GMT,表示在這個時間點之前稳捆,緩存都是有效的赠法。
Expires 是 HTTP1.0 標準中的字段,Cache-Control 是 HTTP1.1 標準中新加的字段乔夯,功能一樣砖织,都是控制緩存的有效時間。當這兩個字段同時出現(xiàn)時末荐,Cache-Control 是高優(yōu)化級的侧纯。
Etag 也是和 Last-Modified 一樣,對文件進行標識的字段甲脏。不同的是眶熬,Etag 的取值是一個對文件進行標識的特征字串。在向服務(wù)器查詢文件是否有更新時块请,瀏覽器通過 If-None-Match 字段把特征字串發(fā)送給服務(wù)器娜氏,由服務(wù)器和文件最新特征字串進行匹配,來判斷文件是否有更新负乡。沒有更新回包304牍白,有更新回包200。Etag 和 Last-Modified 可根據(jù)需求使用一個或兩個同時使用抖棘。兩個同時使用時茂腥,只要滿足基中一個條件,就認為文件沒有更新切省。
另外有兩種特殊的情況:
手動刷新頁面(F5)最岗,瀏覽器會直接認為緩存已經(jīng)過期(可能緩存還沒有過期),在請求中加上字段:Cache-Control:max-age=0朝捆,發(fā)包向服務(wù)器查詢是否有文件是否有更新般渡。
強制刷新頁面(Ctrl+F5),瀏覽器會直接忽略本地的緩存(有緩存也會認為本地沒有緩存)芙盘,在請求中加上字段:Cache-Control:no-cache (或 Pragma:no-cache)驯用,發(fā)包向服務(wù)重新拉取文件。
8儒老、History
用戶訪問網(wǎng)頁的歷史記錄通常會被保存在一個類似于棧的對象中蝴乔,即 history 對象,點擊返回就出棧驮樊,跳下一頁就入棧薇正。 它提供了以下方法來操作頁面的前進和后退:
window.history.back( ) ?返回到上一個頁面
window.history.forward( ) ?進入到下一個頁面
window.history.go( [delta] ) ?跳轉(zhuǎn)到指定頁面
HTML5 對History Api 進行了增強片酝,新增了兩個Api 和一個事件,分別是pushState挖腰、replaceState 和?onpopstate:
pushState是往history對象里添加一個新的歷史記錄雕沿,即壓棧。
replaceState 是替換history對象中的當前歷史記錄猴仑。
當點擊瀏覽器后退按鈕或 js調(diào)用history.back 都會觸發(fā) onpopstate 事件审轮。
與其類似的還有一個事件:onhashchange,onhashchange是老 API辽俗,瀏覽器支持度高断国,本來是用來監(jiān)聽hash變化的,但可以被利用來做客戶端前進和后退事件的監(jiān)聽榆苞,而onpopstate 是專門用來監(jiān)聽瀏覽器前進后退的稳衬,不僅可以支持 hash,非 hash 的同源 url 也支持坐漏。
9薄疚、HTML5離線緩存
HTML5離線緩存又叫Application Cache,是從瀏覽器的緩存中分出來的一塊緩存區(qū)赊琳,如果要在這個緩存中保存數(shù)據(jù)街夭,可以使用一個描述文件(manifest file),列出要下載和緩存的資源躏筏。
manifest 文件是簡單的文本文件板丽,它告知瀏覽器被緩存的內(nèi)容(以及不緩存的內(nèi)容)。manifest 文件可分為三個部分:
CACHE MANIFEST?- 在此標題下列出的文件將在首次下載后進行緩存
NETWORK?- 在此標題下列出的文件需要與服務(wù)器的連接趁尼,且不會被緩存
FALLBACK?- 在此標題下列出的文件規(guī)定當頁面無法訪問時的回退頁面(比如 404 頁面)
離線緩存為應(yīng)用帶來三個優(yōu)勢:
離線瀏覽 - 用戶可在應(yīng)用離線時使用它們
速度 - 已緩存資源加載得更快
減少服務(wù)器負載 - 瀏覽器將只從服務(wù)器下載更新過或更改過的資源埃碱。
10、Web語義化與SEO
Web語義化是指使用語義恰當?shù)臉撕炈峙ⅲ鬼撁嬗辛己玫慕Y(jié)構(gòu)砚殿,頁面元素有含義,能夠讓人和搜索引擎都容易理解芝囤。
SEO是指在了解搜索引擎自然排名機制的基礎(chǔ)之上似炎,對網(wǎng)站進行內(nèi)部及外部的調(diào)整優(yōu)化,改進網(wǎng)站在搜索引擎中關(guān)鍵詞的自然排名悯姊,獲得更多的展現(xiàn)量羡藐,吸引更多目標客戶點擊訪問網(wǎng)站,從而達到互聯(lián)網(wǎng)營銷及品牌建設(shè)的目標悯许。
搜索引擎通過爬蟲技術(shù)獲取的頁面就是由一堆 html 標簽組成的代碼仆嗦,人可以通過可視化的方式來判斷頁面上哪些內(nèi)容是重點,而機器做不到岸晦。 但搜索引擎會根據(jù)標簽的含義來判斷內(nèi)容的權(quán)重欧啤,因此,在合適的位置使用恰當?shù)臉撕炂羯希拐麄€頁面的語義明確邢隧,結(jié)構(gòu)清晰,搜索引擎才能正確識別頁面中的重要內(nèi)容冈在,并予以較高的權(quán)值倒慧。比如h1~h6這幾個標簽在SEO中的權(quán)值非常高,用它們作頁面的標題就是一個簡單的SEO優(yōu)化包券。