[TOC]
# 一、HTML結構
~~~
<!DOCTYPE html>
<html lang="en">
<head>
? ?<!--網頁頁面字符集-->
? ?<meta charset="UTF-8">
? ?
? ?<!--針對移動設備,網站顯示寬度等于設備屏幕顯示寬度,內容縮放比例為1:1-->
? ?<meta name="viewport" content="width=device-width, initial-scale=1.0">
? ?
? ?<!--讓IE使用最新的渲染模式-->
? ?<meta http-equiv="X-UA-Compatible" content="ie=edge">
? ?
? ?<!--將下面的 <meta> 標簽加入到頁面中,可以讓部分國產瀏覽器默認采用高速模式渲染頁面:-->
? ?<meta name="renderer" content="webkit">
? ?<!-- 上述3個meta標簽*必須*放在最前面,任何其他內容都*必須*跟隨其后! -->
? ?
? ?<title>xx頁面</title>
? ?
? ?<!-- css樣式文件放在head標簽尾部,body的前面:邊解析css邊解析dom,解析完一起渲染,而不是渲染完一遍解析了樣式文件再重新渲染 -->
? ?<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
? ?<div id="container">default</div>
? ?<p>test</p>
? ?
? ?<!-- js腳本文件放在body標簽尾部,防止阻塞渲染 -->
? ?<script src="index.js"></script>
? ?<!-- 這里src引用的是本地.線上建議使用CDN引用 -->
</body>
</html>
~~~
## 1\. DOCTYPE
### 1-1. DOCTYPE是什么?
* DOCTYPE是用來聲明**文檔類型**和DTD(Document Type Definition)規范的。 瀏覽器據此來選擇用什么引擎去**解析/渲染**它。
* `<!DOCTYPE html>`聲明位于HTML文檔中的第一行,不是一個HTML標簽,處于 html 標簽之前。DOCTYPE不存在或格式不正確會導致文檔以**兼容模式**呈現。
### 1-2. DOCTYPE分類?
* **HTML5的模式**`<!DOCTYPE html>`,不像HTML4基于SGML(標準通用標記語言),所以不用指定DTD;
* **HTML4的嚴格/標準模式**,會聲明一個**strict.dtd**規范,表明該DTD包含所有HTML元素和屬性,但是**不包括**展示性和棄用的元素,比如font。該模式以該瀏覽器支持的最高標準運行;
* **HTML4的傳統/兼容模式**,會聲明一個**loose.dtd**規范,表明該DTD包含所有HTML元素和屬性,**包括**展示性和棄用的元素。頁面以寬松的向后兼容的方式顯示,模擬老式瀏覽器的行為以防止站點無法工作。
## 2\. HTML標簽
### 2-1. html標簽
`<html lang="en">`,**語言**,必須定義并且包含在 `html` 標簽中
### 2-2. head標簽
* **head**標簽的**meta元素**大概分為三類,分別是:
* 描述**網頁基本信息**的
* 指向渲染網頁需要**其他文件鏈接**的
* 各大廠商根據自己需要**定制**的
* **1\. 網頁基本信息**
* **文檔標題**(瀏覽器標簽中顯示的文本):`<title>`
* **字符編碼**:如果頁面出現亂碼,一般是編碼格式不對 `<meta charset="utf-8">`
* **視窗設置**:`<meta name="viewport" content="width=device-width, initial-scale=1.0">`
* 搜索引擎優化相關內容:`<meta property="og:description" content="前端故事">`
* **兼容IE**設置:`<meta http-equiv="X-UA-Compatible" content="ie=edge">`
* **2\. 其他文件鏈接**
* CSS 文件:`<link rel="stylesheet" href="style.css" type="text/css" media="all" />`
* JavaScript 文件:`<script type="text/javascript" src="integrator.js"></script>` 但是為了讓頁面的樣子更早的讓用戶看到,一般把JS文件放到body的底部
* **3\. 廠商定制** 同樣分享頁面到QQ的聊天窗口,有些頁面直接就是一個鏈接,但是有些頁面有標題,圖片,還有文字介紹。為什么區別這么明顯呢?其實就是看有沒有設置下面這三個內容
~~~
<meta itemprop="name" content="這是分享的標題"/>
<meta itemprop="image" content="http://imgcache.qq.com/qqshow/ac/v4/global/logo.png" />
<meta name="description" itemprop="description" content="這是要分享的內容" />
~~~
### <mark>2-3. 行內、塊級等元素分類</mark>
定義:CSS 規范規定,每個元素都有 **display**屬性,確定該元素的類型,每個元素都有默認的 display 值,如 div 的 display 默認值**為“block”,則為“塊級”元素**;span 默認 display 屬性值**為“inline”,是“行內”元素**。
* 行內元素(display:inline)
* **a b span img input select strong**
* 塊級元素(display:block)
* **div ul ol li dl dt dd h1 h2 h3 h4…p**
* 空(void)元素
* **br hr img input link meta**
* 自閉和元素
* **input img br hr meta link**
### 2-4. 幾種標簽作用
#### 2-4-1. href 和 src的區別?
* href 表示超文本引用(hypertext reference),在 **link和a** 等元素上使用。
* href 的內容,是與該頁面有關聯,是引用。
* `<link href="common.css" rel="stylesheet"/>` 瀏覽器會識別該文檔為css文件,就會**并行下載資源**并且**不會停止對當前文檔的處理**。這也是為什么建議使用link方式來加載css,而不是使用@import方式。
* src 表示來源地址,在 **img、script、iframe** 等元素上。
* src 的內容,是頁面必不可少的一部分,是引入。
* `<script src ="js.js"></script>` 當瀏覽器解析到該元素時,會**暫停其他資源的下載和處理**,直到將**該資源加載、編譯、執行完畢**,圖片和框架等元素也如此,類似于將所指向資源嵌入當前標簽內;這也是為什么將js腳本放在底部而不是頭部。
#### 2-4-2. 為什么我們要棄用**table標簽**?
* 瀏覽器從服務器加載代碼時,本應是加載一行執行一行,但是table標簽是里面的東西**全都下載完之后才會顯示出來**,內容很多就會導致很長時間一直加載不出來。
#### 2-4-3. form表單元素的作用?
* **直接提交**表單
* 使用**submit / reset**按鈕
* 便于瀏覽器**保存**表單
* 第三方庫可以**整體取值**
* 第三方庫可以進行**表單驗證**
#### 2-4-4. HTML5 的 **form** 如何關閉自動補全功能?
* 給不想要提示的 form 或某個 input 設置為 `autocomplete=off`。
#### 2-4-5. **img**的alt屬性和title屬性有何區別?
* ~~~
<img src="#" alt="alt信息" title="title信息" />
~~~
* alt屬性是在圖片未正常輸出時顯示的文字;
* title屬性為圖片/鏈接添加描述性文字,鼠標hover上去出現提示性信息。
#### 2-4-6. 說說title屬性?
* title 屬性可以用在除了 base,basefont,head,html,meta,param,script 和 title 之外的**所有標簽**。
* title 屬性的功能是提示。額外的說明信息和非本質的信息請使用 title 屬性。title 屬性值**可以比 alt 屬性值設置的更長**。
* title 屬性有一個很好的用途,即為**鏈接**添加描述性文字,特別是當鏈接本身并不是十分清楚的表達了鏈接的目的。
#### 2-4-7. **label**的作用是什么?怎么使用?
* **label 標簽**來定義表單控制間的關系,當用戶選擇該標簽時,瀏覽器會自動將焦點轉到和標簽相關的表單控件上。
* ~~~
<label for="Name">Number:</label> <input type="text" name="Name" id="Name"/>
<label>Date:<input type="text" name="B"/></label>
~~~
* 兩種方式是前后/包住input;前后需要for屬性指向input的name屬性;包住不需要。
#### <mark>2-4-8. **iframe**是什么?優缺點?</mark>
* **定義**:**iframe元素會創建包含另一個文檔的內聯框架**
* **提示**:可以將提示文字放在之間,來提示某些**不支持iframe**的瀏覽器
* **優點:**
1. iframe能夠把嵌入的網頁原封不動的**展現**出來
2. 如果有**多個網頁引用**iframe,那么你只需要修改iframe的內容,就可以實現調用的每一個頁面內容的更改,方便快捷
3. 網頁如果**為了統一風格**,頭部和版本都是一樣的,就可以寫成一個頁面,用iframe來嵌套,可以**增加代碼的可重用**
4. 如果遇到**加載緩慢**的第三方內容如圖標和廣告,這些問題可以由iframe來解決
* **缺點:**
1. iframe會**阻塞主頁面的onload**事件
2. iframe和主頁面**共享連接池**,而**瀏覽器對相同域的連接有限制**,所以會影響頁面的**并行加載**,會產生很多頁面,不容易管理
3. iframe框架結構有時會讓人感到迷惑,如果框架個數多的話,可能會出現**多個上下、左右滾動條**,會分散訪問者的注意力,**用戶體驗度差**
4. 代碼復雜,無法被一些搜索引擎索引到,這一點很關鍵,現在的搜索引擎爬蟲還不能很好的處理iframe中的內容,所以使用iframe會**不利于搜索引擎優化**(SEO)
5. 很多的移動設備無法完全顯示框架,**移動設備兼容性差**
6. iframe框架頁面會**增加服務器的http請求**,對于大型網站是不可取的
* 如果需要使用iframe,最好是通過javascript**動態給iframe添加src屬性值**,這樣可以繞開以上一些問題。
## 3\. 其他
### 3-1. HTML語義化
#### 3-1-1. 語義化的意義?
**HTML5**語義化標簽是指**正確的標簽包含正確的內容**
* **代碼結構**:html 語義化讓頁面的內容**結構化**,結構更清晰,便于對瀏覽器、搜索引擎解析;即使在沒有樣式 CSS 情況下也以一種文檔格式顯示,并且是**容易閱讀**的
* **有利于SEO**:搜索引擎的爬蟲也依賴于 HTML 標記來確定上下文和各個關鍵字的權重,**利于 SEO**(搜索引擎優化)
* **提升用戶體驗**:使閱讀源代碼的人對網站更容易將**網站分塊**,便于**閱讀、維護、理解**
* 比如**nav**表示導航條,類似的還有article、header、footer等等標簽。

#### <mark>3-1-2. 語義化舉例?</mark>
* *em* 標簽是強調;
*i* 標簽是斜體,無語義
* **strong** 標簽是重點強調; **b** 標簽是粗體,無語義
* **h1** 則表示層次明確的標題,對頁面信息的抓取也有很大的影響
**title** 沒有明確意義只表示是個標題
* `我是code標簽`,~我是del標簽~,我是ins標簽 【語義化】
### 3-2. Web Quality是什么?
[Web品質](http://www.xiaoushuo.com/quality/quality-styles.html),分為幾個方面:
* **HTML標簽元素**,遵循語義化,比如標題的嵌套,還有header、footer、nav等等
* **CSS樣式表**,注意背景顏色、字體的一致性,以及可讀性
* 細節,排版文字的**行距,居中**,避免過于花哨
* **WAI無障礙**,能夠被殘障人士使用的網站,字體大小的調整,合理利用**img的alt屬性**
* **國際化**,統一**字符集**charset:UTF-8國際標準,國際**日期**格式
### 3-3. document.write 和 innerHTML 的區別
* document.write 只能重繪整個頁面
* innerHTML 可以重繪頁面的一部分
### 3-4. innerText屬性和innerHTML屬性的區別
前者會過濾掉html標簽獲取文本,后者不會過濾。
* innerText屬性
~~~
document.getElementById('box').innerText; //獲取文本內容(如有html 直接過濾掉)
document.getElementById('box').innerText = '<div>Mr.Lee</div>'; //設置文本(如有html會進行轉義)
~~~
* innerHTML屬性
~~~
document.getElementById('box').innerHTML; //獲取文本(不過濾HTML)
document.getElementById('box').innerHTML = '<b>123</b>'; //可解析成HTML
~~~
# 二、HTML5
## 1\. HTML5特性?
### 1-1. 增刪元素?
* HTML5 現在已經不是 SGML(標準通用標記語言) 的子集,主要是關于**圖像,位置,存儲,多任務**等。
* 增加的元素?
* [語義化元素](http://www.w3school.com.cn/html/html5_new_elements.asp),比如 **header、footer、nav、aside、main、article、section**
* 內容元素,比如mark高亮、progress進度條
* [表單增強](http://caibaojian.com/html5/form.html),**color、range、calendar、date、time、email、url、search**
* 新的API
* 圖形 (canvas)
* 音視頻 (audio, vidio)
* **離線存儲 (applicationCache )**
* **本地存儲(localStorage,sessionStorage, indexDB)**
* **實時通信(websoket)**
* **設備能力(Geolocation地圖定位,手機搖一搖)**
* 頁面可見性(Page Visibility)
* 移除的元素?
* 純表現的元素:basefont,**big**,center,**font**, s,strike,tt,u;
* 對可用性產生負面影響的元素:**frame**,**frameset**,noframes;
### 1-2. 區分與兼容性?
* 如何**區分** HTML5: **DOCTYPE 聲明\\新增的結構元素\\功能元素**
* IE8/IE7/IE6 支持通過 **document.createElement**方法產生標簽,可以利用這一特性讓這些瀏覽器支持 HTML5 新標簽
* 瀏覽器支持新標簽后,還需要添加標簽默認的樣式
* 當然也可以直接使用**成熟的框架**、比如 **html5shim**;
~~~
<!--[if lt IE 9]>
? ? ?<script>
? ? ? ? src = 'http://html5shim.googlecode.com/svn/trunk/html5.js'
? ? ?</script>
? ?<![endif]-->
~~~
## <mark>2\. 新的API?</mark>
### 2-1. canvas和svg區別?
* **歷史**:
* **canvas**是html5**提供的**新元素**,而svg存在的歷史要比canvas久遠,已經有**十幾年了。
* **svg**并**不是html5**專有的標簽,最初svg是用**xml技術**(超文本擴展語言,可以自定義標簽或屬性)描述二維圖形的語言。在H5中看似canvas與svg很像,但是,他們有巨大的差別。
* **應用**:
* 首先,從它們的功能上來講,**canvas可以看做是一個畫布**,其繪制出來的圖形為**標量圖**,因此,可以在canvas中引入jpg或png這類格式的圖片,在實際開發中,大型的**網絡游戲**都是用canvas畫布做出來的,并且canvas的技術現在已經相當的成熟。另外,我們喜歡用canvas來做一些**統計圖表**,如柱狀圖曲線圖或餅狀圖等。
* 而**svg**,所繪制的圖形為**矢量圖**,所以其用法上受到了限制。因為只能繪制矢量圖,所以svg中不能引入普通的圖片,因為矢量圖的不會失真的效果,在項目中我們會用來**做小圖標**。但是由于其本質為矢量圖,可以**被無限放大而不會失真**,這很適合被用來**做地圖**,而**百度地圖**就是用svg技術做出來的。
* **引擎抓取和事件綁定**:
* 另外從技術發面來講canvas里面繪制的圖形**不能被引擎抓取**,如我們要讓canvas里面的一個圖片跟隨鼠標事件: `canvas.onmouseover=function(){}`。
* 而svg里面的圖形**可以被引擎抓取**,**支持事件的綁定**。另外canvas中我們繪制圖形通常是通過javascript來實現,svg更多的是通過標簽來來實現,如在svg中繪制正矩形形就要用`<rect>` ,這里我們不能用屬性`style="width:XXX;height:XXX;"`來定義。一個svg的js庫:two.js。
### 2-2. 離線儲存 **applicationCache** 工作原理?
* **appcache**是一種緩存機制,不是存儲技術。
在用戶**沒有聯網**時,可以正常訪問站點或應用,在用戶**聯網**時,更新用戶機器上的緩存文件。
* **原理**:**HTML5**的離線存儲是基于一個**新建的.appcache 文件**的緩存機制,通過這個文件上的解析離線存儲資源清單,這些資源就會像 cookie 一樣被存儲了下來。之后當網絡處于離線狀態時,瀏覽器會通過離線存儲的數據進行頁面展示。
* **使用方法**:如需啟用應用程序緩存,請在文檔的`<html>`標簽中包含 `<manifest>` 屬性:
~~~
<!DOCTYPE html>
<html manifest="demo_html.appcache">
<body>
----主體內容----
</body>
</html>
~~~
manifest 文件的建議的文件擴展名是:".appcache",示例如下:
~~~
CACHE MANIFEST
? ? ?#v1.0
? ? ?
? ? CACHE: //在此標題下列出的文件將在首次下載后進行緩存
? ? js/app.js
? ? css/style.css
? ? ?
? ? NETWORK: //在此標題下列出的文件需要與服務器的連接,且不會被緩存
? ? assets/logo.png
? ? ?
? ? FALLBACK: //在此標題下列出的文件規定當頁面無法訪問時的回退頁面(比如 404 頁面)
? ? /html5/ /404.html
~~~
#### 2-2-1. 瀏覽器是怎么對 HTML5 的離線儲存資源進行管理和加載的呢?
* 在線的情況下,瀏覽器發現 html 頭部有 **manifest屬性**,它會**請求 manifest 文件**
* 如果是**第一次訪問** 服務器/應用,那么瀏覽器就會根據 manifest 文件的內容下載相應的資源并且進行離線存儲
* 如果已經訪問過服務器/應用并且資源已經離線存儲了,那么瀏覽器就會使用**離線的資源加載頁面**;然后瀏覽器會**對比**新的 manifest 文件與舊的 manifest 文件
* 如果文件沒有發生改變,就不做任何操作
* 如果文件改變了,那么就會**重新下載文件中的資源**并進行離線存儲
* **離線**的情況下,瀏覽器就直接使用離線存儲的資源。 在離線狀態時,操作 window.applicationCache 進行需求實現。
參考鏈接:[HTML5 離線緩存-manifest 簡介](https://yanhaijing.com/html/2014/12/28/html5-manifest/)
#### 2-2-2. applicationCache的優點?
~~~
1. 離線瀏覽 - 用戶可以在離線時使用應用程序
2. 快速 - 緩存的資源可以更快地加載
3. 減少服務器加載 - 瀏覽器只從服務器上下載已更新/已更改的資源
~~~
### <mark>2-3. ★本地存儲Cookie、LocalStorage、SessionStorage的區別?</mark>
* **攜帶**
* cookie 是網站為了標示用戶身份而儲存在客戶端上的數據(通常經過加密),會在客戶端和服務器之間**來回傳遞**【始終在同源的 http 請求中攜帶(即使不需要)】,而且始終放在http頭部,較大會**影響性能**
* SessionStorage 和 localStorage 不會自動把數據發給服務器,**僅在本地**保存。
* **存儲大小**
* cookie 數據大小不能超過 **4k**,很多瀏覽器都限制一個站點最多保存20個cookie。
* sessionStorage 和 localStorage 是HTML5專門設計,存儲容量比 cookie 大得多,可以達到 **5M** 或更大。
* **有效期**(生命周期)
* localStorage: **存儲持久數據**,瀏覽器關閉后數據不丟失**除非主動刪除**數據;
* SessionStorage: 數據在**當前瀏覽器窗口關閉**后自動刪除。
* cookie: 設置的 cookie **過期時間max-age/expires**之前一直有效,即使窗口或瀏覽器關閉
* **API易用性**
* cookie需要使用document.cookie來獲取和修改,而且必須使用key-value的對象格式存儲。API簡單,**需要封裝**才能使用
* sessionStorage 和 localStorage 的API**簡單易用**,直接使用localStorage.**setItem**(key,value)和localStorage.**getItem**(key)即可
* **共享**
* sessionStorage**不能共享(即使是同一個頁面不同的窗口)**
* localStorage在**同源文檔**之間共享
* cookie在**同源且符合path**規則的文檔之間共享
* **應用**
* 從安全性來說,因為每次http請求都回攜帶cookie信息,這樣浪費了帶寬,所以cookie應該盡可能的少用,此外cookie還需要指定作用域,不可以跨域調用,限制很多,但是**用戶識別用戶登**陸來說,**cookie**還是比storage好用
* 其他情況下可以用storage
* **localstorage**可以用來在**頁面內傳遞參數**
* **sessionstorage**可以用來保存些**臨時的數據**,防止刷新頁面后丟失一些參數

### 2-4. WebSocket的實現和應用

* 為了建立一個 WebSocket 連接,客戶端瀏覽器首先要向服務器發起一個 HTTP 請求,這個請求和通常的 HTTP 請求不同,包含了一些附加頭信息,其中附加頭信息"**Upgrade: WebSocket**"表明這是一個申請協議升級的 HTTP 請求。
* 服務器端解析這些附加的頭信息然后產生應答信息返回給客戶端,客戶端和服務器端的 WebSocket 連接就建立起來了,雙方就可以通過這個連接通道自由的傳遞信息,并且這個連接會**持續存在直到客戶端或者服務器端的某一方主動的關閉連接**。
* 當你獲取 Web Socket連接后,你可以通過**send()方法來向服務器發送數據,并通過onmessage**事件來接收服務器返回的數據。 以下 **API 用于創建 WebSocket** 對象。
~~~
var Socket = new WebSocket(url, [protocol] );
~~~
#### <mark>2-4-1. WebSocket和HTTP的區別?</mark>
* HTTP的生命周期通過Request來界定,也就是一個Request一個Response,那么在Http1.0協議中,這次Http請求就結束了。在Http1.1中進行了改進,有一個**connection:Keep-alive**,也就是說,在一個Http連接中,可以發送多個Request,接收多個Response。但是必須記住,在Http中一個Request只能對應有一個Response,而且這個Response是**被動的**,不能主動發起。
* WebSocket是基于Http協議的,或者說借用了Http協議來完成一部分握手,在握手階段與Http是相同的。我們來看一個websocket握手協議的實現,基本是2個屬性,**upgrade,connection**。
* WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,允許**服務端主動向客戶端推送數據**。在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行**雙向數據傳輸**。
#### 2-4-2. 什么是WebSocket?
* [WebSocket](https://www.runoob.com/html/html5-websocket.html)是HTML5中一種在**單個 TCP 連接**上進行全雙工通訊的協議,支持**持久連接**;http協議不支持持久性連接。HTTP1.0和HTTP1.1都不支持持久性的連接,HTTP1.1中的keep-alive,**將多個http請求在1個TCP連接上實現**。
* 應用:**實時通信應用**\[微信網頁版\]
#### 2-4-3. WebSocket具體有什么優點?
* WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,允許**服務端主動向客戶端推送數據**。在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行**雙向數據傳輸**。
基本請求如下:
~~~
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket //表示客戶端希望升級到 Websocket 協議
Connection: Upgrade //表示客戶端希望連接升級
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
~~~
* 多了下面2個屬性:
1. `Upgrade:webSocket`
2. `Connection:Upgrade`
* 告訴服務器發送的是 **websocket**
* `Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==`
* `Sec-WebSocket-Protocol: chat, superchat`
* `Sec-WebSocket-Version:13`
#### 2-4-4. WebSocket如何兼容低版本瀏覽器?
* 使用**flash**或其他方法實現一個websocket客戶端(Adobe Flash Socket );
* 基于**長輪詢/長連接**的 XHR;
* ActiveX HTMLFile (IE) ;
* 基于 multipart 編碼發送 XHR ;
* **輪詢**:客戶端定時向服務器發送Ajax請求,服務器接到請求后馬上返回響應信息并關閉連接。
* 優點:后端程序編寫比較容易。
* 缺點:請求中有大半是無用,浪費帶寬和服務器資源。
* 實例:適于小型應用。
* **長輪詢**:客戶端向服務器發送Ajax請求,**服務器接到請求后hold住連接,直到有新消息才返回響應信息并關閉連接**,客戶端處理完響應信息后再向服務器發送新的請求。
* 優點:在無消息的情況下不會頻繁的請求,耗費資源小。
* 缺點:服務器hold連接會消耗資源,返回數據**順序無保證**,難于管理維護。
* 實例:WebQQ、Hi網頁版、Facebook IM。
* **長連接**:在頁面里嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設為對一個長連接的請求或是采用xhr請求,服務器端就能源源不斷地往客戶端輸入數據。
* 優點:消息即時到達,不發無用請求;管理起來也相對方便。
* 缺點:服務器維護一個長連接會增加開銷。
* 實例:**Gmail聊天**
* Flash Socket:在頁面中內嵌入一個使用了Socket類的 Flash 程序,JavaScript通過調用此Flash程序提供的Socket接口與服務器端的Socket接口進行通信,JavaScript在收到服務器端傳送的信息后控制頁面的顯示。
* 優點:實現真正的即時通信,而不是偽即時。
* 缺點:**客戶端必須安裝Flash插件**;非HTTP協議,無法自動穿越防火墻。
* 實例:網絡互動游戲。
### 2-5. WebWorker的實現和應用
#### 2-5-1. WebWorker是什么,有什么優缺點?
[**web worker**](https://www.w3school.com.cn/html5/html_5_webworkers.asp)是運行在**后臺的 JavaScript**,不會影響頁面的性能。
* 當在 HTML 頁面中執行普通腳本時,頁面的狀態是不可響應的,直到腳本已完成。
* web worker 是運行在**后臺**的 JavaScript,獨立于其他腳本,不會影響頁面的性能。
* Web Worker 的作用,就是為 JavaScript 創造**多線程環境**,允許主線程創建 Worker 線程,將一些任務分配給后者運行。在主線程運行的同時,Worker 線程在后臺運行,兩者**互不干擾**。等到 Worker 線程完成計算任務,再把結果返回給主線程。
* 優點:
* 一些計算**密集型或高延遲**的任務,被 Worker 線程負擔了,**主線程**(通常負責 UI 交互)就會很流暢,**不會被阻塞**或拖慢。
* **Worker 線程**一旦新建成功,就會始終運行,**不會被主線程**上的活動(比如用戶點擊按鈕、提交表單)**打斷**。這樣**有利于隨時響應主線程的通信**。
* 缺點:
* 但是,這也造成了 Worker 比較**耗費資源**,不應該過度使用,而且一旦使用完畢,就應該關閉。
#### 2-5-2. WebWorker的創建方法?
主要是**postMessage**和**onmessage**
* **檢測**瀏覽器的支持性 `typeof Worker !== "undefined"`
* **創建**demo\_worker.js文件,傳送消息 `postMessage('消息內容');`
* **創建**實例化對象 `w = new Worker("demo_worker.js")`
* **接收**消息 `w.onmessage = function(event){//TODO}`
* **終止**Webworker `w.terminate()`
#### 2-5-3. WebWorker使用注意事項?
1. **同源限制** 分配給 Worker 線程運行的腳本文件,必須與**主線程的腳本文件同源**。
2. **DOM 限制** Worker 線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網頁的 DOM 對象,也**無法使用`document`、`window`、`parent`這些對象**。但是,Worker 線程可以`navigator`對象和`location`對象。
3. **通信聯系** Worker 線程和主線程不在同一個上下文環境,它們不能直接通信,必須**通過消息**完成。
4. **腳本限制** Worker 線程不能執行`alert()`方法和`confirm()`方法,但可以使用 XMLHttpRequest 對象發出 **AJAX** 請求。
5. **文件限制** Worker 線程無法讀取本地文件,即不能打開本機的文件系統(`file://`),它所加載的**腳本**,**必須來自網絡**。
### 2-6. SharedWorker是什么?
> ##### **共享worker(SharedWorker)**,這種是可以多個標簽頁、iframe共同使用的,可以實現標簽頁之間的通信。SharedWorker可以被多個window共同使用,但必須保證這些標簽頁都是同源的(相同的協議,主機和端口號)
>
> [舉例1](https://www.jianshu.com/p/31facd4934d7):但是不支持本地運行,需放到服務器。
#### 2-6-1. SharedWorker的創建方法?
* **檢測**瀏覽器的支持性`typeof Worker !== "undefined"`
* 創建worker.js文件,監聽消息事件 `onmessage`
* 消息里有`get`就傳送消息`postMessage('消息內容')`到客戶端
* 否則就把客戶端傳遞過來的數據存儲到data變量
* **創建**對象`w = new SharedWorker("demo_worker.js")`
* **請求**使用postMessage來傳遞發送數據的請求data以及獲取數據的請求ge
* 頁面A發送數據給worker,然后打開頁面B
* 調用`window.worker.port.postMessage('get')`,即可收到頁面A發送給worker的數據
* 調用`window.worker.port.postMessage('發送內容')`,即可傳送數據到sharedWorker
### <mark>2-7. drag API包含哪些?</mark>
1. **dragstart**:事件主體是被拖放元素,在**開始拖放**被拖放元素時觸發,。
2. **drag**:事件主體是被拖放元素,在**正在拖放**被拖放元素時觸發。
3. **dragenter**:事件主體是目標元素,在被拖放元素**進入某元素**時觸發。
4. **dragover**:事件主體是目標元素,在被拖放**在某元素內移動**時觸發。
5. **dragleave**:事件主體是目標元素,在被拖放元素**移出目標元素**是觸發。
6. **drop**:事件主體是目標元素,在**目標元素完全接受**被拖放元素時觸發(完全進入)。
7. **dragend**:事件主體是被拖放元素,在整個**拖放操作結束**時觸發。
* [具體使用](https://www.cnblogs.com/yangguoe/p/9681692.html):
~~~
cat.ondragstart = function(e){
? ?console.log('cat開始移動');
? ?offsetX = e.offsetX;
? ?offsetY = e.offsetY;
};
~~~
### 2-8. Geolocation[地圖定位](https://www.runoob.com/html/html5-geolocation.html)
~~~
navigator.geolocation.getCurrentPosition(showPosition,showError)
~~~
* 實例流程
* 檢測是否支持地理定位
* 如果支持,則運行 **getCurrentPosition()方法**。如果不支持,則向用戶顯示一段消息。
* 如果getCurrentPosition()運行成功,則向參數showPosition中規定的函數返回一個coordinates對象
* **showPosition() 函數**獲得并顯示經度和緯度
### 2-9. 頁面可見性(Page Visibility API) 可以有哪些用途?
* 通過 visibilityState 的值檢測頁面當前是否可見,以及打開網頁的時間等;
* 在頁面被切換到其他后臺進程的時候,自動暫停音樂或視頻的播放;
* [參考](https://www.jianshu.com/p/cd8011bc9f8e)
## 3\. 應用?
### <mark>3-1. 如何實現瀏覽器內多個標簽頁之間的通信?</mark>
* **WebSocket**、**SharedWorker**;【postMessage、onmessage】
* 也可以調用 **localstorage、cookies** 等本地存儲方式; **localstorage** 另一個瀏覽上下文里被添加、修改或刪除時,它都會觸發一個`storage`事件,我們通過監聽事件,控制它的值來進行頁面信息通信; **“當同源頁面的某個頁面修改了localStorage,其余的同源頁面只要注冊了storage事件,就會觸發”** 所以,`localStorage` 的例子運行需要如下條件:
* 同一瀏覽器打開了兩個同源頁面
* 其中一個網頁修改了 `localStorage`
* 另一網頁注冊了 `storage` 事件
1. 在同源的兩個頁面中,可以**監聽 storage 事件**
~~~
window.addEventListener("storage", function (e) {
? ? ? ?alert(e.newValue);
});
~~~
2. 在同一個頁面中,**對 `localStorage` 的 `setItem` 方法進行重寫**
~~~
var orignalSetItem = localStorage.setItem;
localStorage.setItem = function(key,newValue){
? ? ?var setItemEvent = new Event("setItemEvent");
? ? ?setItemEvent.newValue = newValue;
? ? ?window.dispatchEvent(setItemEvent);
? ? ?orignalSetItem.apply(this,arguments);
}
window.addEventListener("setItemEvent", function (e) {
? ?alert(e.newValue);
});
localStorage.setItem("name","wang");
~~~
**注意** quirks:Safari 在無痕模式下設置 localstorge 值時會拋出 QuotaExceededError 的異常。
### <mark>3-2. 如何實現實時通信?</mark>
* 現在,很多網站為了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,然后由服務器返回最新的數據給客戶端的瀏覽器。這種**傳統的模式**帶來很明顯的缺點,即**瀏覽器需要不斷的向服務器發出請求**,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會**浪費很多的帶寬等資源。**
* HTML5 定義的 WebSocket 協議支持服務端push,能更好的節省服務器資源和帶寬,并且能夠更實時地進行通訊。
* 因此我們可以通過WebSocket實例化對象,上面掛載的onopen方法建立連接時觸發,**send**方法發送數據時觸發,**onmessage**方法在接收數據時觸發,onerror/onclose…
- 引言
- 一、HTML&CSS
- 1.html
- 2.瀏覽器
- 3.CSS
- 4.場景設計
- 二、JS
- 1.JS基礎
- 2.原型和原型鏈
- 3.異步和單線程
- 4.閉包和作用域
- 三、ES6
- 1.ES6新增語法
- 1.let
- 2.Symbol
- 3.解構賦值
- 4.字符串API
- 5.數組API
- 6.map和reduce
- 7.對象API
- 8.Map和WeakMap
- 9.Set和WeakSet
- 10.Map、Set與Array及Object
- 11.Proxy和Reflect
- 12.Proxy雙向綁定
- 2.ES6函數和異步
- 0.Class
- 1.函數的擴展
- 2.箭頭函數
- 3.類
- 4.Decorator
- 5.模塊化開發
- 6.異步實現方式
- 7.Promise
- 8.Iterator
- 9.Generator
- 10.async
- 11.Promise-Generator-async
- 四、運行環境
- 1.網絡基礎
- 2.web安全
- 3. 性能優化
- 3-1.頁面渲染優化
- 3-2.JS性能優化
- webpack優化
- 3-3.網絡優化
- CDN
- 3-4 SEO優化
- 4. 瀏覽器兼容性
- 5. 移動端題目
- 6. 錯誤監控
- 7. 垃圾回收與內存泄露
- 8. 單頁路由
- 五、類庫框架
- 1. Vue
- 1-1. jquery和vue
- 1-2. react和vue
- 1-3. 微信小程序與vue
- 生命周期
- 組件傳值
- 雙向綁定解析
- 2. 微信小程序
- 六、構建工具
- 1. webpack
- 常用loader
- babel
- 2. rollup
- 七、nodejs
- 基礎
- npm包管理工具
- 八、模塊化
- 1. 模塊化
- 2. 模塊意義
- 3. AMD-requirejs
- 4. CommonJS
- 5. ES6模塊化之babel
- 九、拓展
- 1. Graphql
- 2. Apache
- 十、代碼輸出問題
- 內容
- 結語