1. 本文是在學(xué)習(xí)廖雪峰先生的JavaScrip教程 后的歸納
一、瀏覽器對象
- 常用的瀏覽器: Chrome,Firefox,Sarafi
- window 對象
-
window對象不但充當(dāng)全局作用域,而且表示瀏覽器窗口 -
window對象有innerWidth和innerHeght屬性,可以獲取瀏覽器窗口的內(nèi)部寬度和高度(內(nèi)部寬高指的是除去菜單欄、工具欄、邊框等占位元素后,用于顯示網(wǎng)頁的凈寬高) -
outerWidth和outerHeight屬性,可以獲取瀏覽器窗口的整個(gè)寬高 -
navigator對象表示瀏覽器的信息,最常用的屬性包括:-
navigator.appName: 瀏覽器名稱; -
navigator.appVersion:瀏覽器版本; -
navigator.language: 瀏覽器設(shè)置的語言 -
navigator.platform: 操作系統(tǒng)類型 -
navigator.userAgent:瀏覽器設(shè)定的User-Agent字符串 -
navigator的值可以被用戶修改,JavaScript讀取的值不一定正確
-
-
- screen對象
-
screen對象表示屏幕的信息,常用的屬性有:-
screen.width:屏幕寬度,以像素為單位 -
screen.height: 屏幕高度,以像素為單位 -
screen.colorDepth:返回顏色位數(shù),如8、16、24
-
-
- location對象
-
location對象表示當(dāng)前頁面的URL信息-
location.protocol; //'http' -
location.host;//'www.example.com' -
location.port;//'8080' -
location.pathname;//'/path/index.html` -
location.search;//'?a=1&b=2' -
location.hash;//'TOP' -
location.assign('')//加載一個(gè)新頁面 -
location.reload()//重新加載當(dāng)前頁面
-
-
- document對象
-
document對象表示當(dāng)前頁面,由于HTML在瀏覽器中以DOM形式表示為樹形結(jié)構(gòu),document對象就是整個(gè)DOM數(shù)的根節(jié)點(diǎn) -
document的title屬性是從HTML文檔中<title>xxx<title>讀取的,可以動態(tài)改變document.title='ab'; -
查找DOM數(shù)的某個(gè)節(jié)點(diǎn),需要從document對象開始查找,最常用的查找是根據(jù)ID和TAGName` -
document對象提供的getElementeById()和getElementsByTagName() -
document還有一個(gè)cookie屬性,可以獲取當(dāng)前頁面的cookie - Cookie是有服務(wù)器發(fā)送的
key-value標(biāo)識符, 因?yàn)镠TTP協(xié)議是無狀態(tài)的,服務(wù)器使用Cookie區(qū)分哪個(gè)用戶 - Cookie還存儲網(wǎng)站的一些設(shè)置:如頁面顯示的語言等
- JavaScript通過
document.cookie讀取到當(dāng)前頁面的Cookie - 為了安全,服務(wù)器端設(shè)置Cookie時(shí)可以使用
httpOnly,設(shè)定了httpOnly的Cookie將不能被JavaScript讀取,這個(gè)行為由瀏覽器實(shí)現(xiàn),主流瀏覽器均支持httpOnly選項(xiàng)
-
- histroy對象
- history 對象保存了瀏覽器的的歷史記錄
- 調(diào)用
history對象的back()或forward()后退或前進(jìn) - 由于交互不好,建議不要使用
history對象
二、操作DOM
- DOM簡介
- DOM是一個(gè)樹形結(jié)構(gòu)
- 操作DOM的操作有:
- 更新: 更新該DOM節(jié)點(diǎn)的內(nèi)容
- 遍歷: 遍歷該DOM節(jié)點(diǎn)下的子節(jié)點(diǎn)
- 添加: 添加子節(jié)點(diǎn)
- 刪除: 從HTML中刪除該節(jié)點(diǎn)
- 取得節(jié)點(diǎn)方法有:
document.getElementById()和document.getElementByTagName(),以及CSS選擇器document.getElementsByClassName() -
document.getElemnetById()定位唯一的一個(gè)DOM節(jié)點(diǎn),而document.getElementByTagName()和documente.getElementesByClassName()返回一組DOM節(jié)點(diǎn) -
querySelector()和querySelectorAll()
// 通過querySelector獲取ID為q1的節(jié)點(diǎn): var q1 = document.querySelector('#q1'); // 通過querySelectorAll獲取q1節(jié)點(diǎn)內(nèi)的符合條件的所有節(jié)點(diǎn): var ps = q1.querySelectorAll('div.highlighted > p'); 注意:低版本的IE<8不支持querySelector和querySelectorAll。IE8僅有限支持。- DOM節(jié)點(diǎn)實(shí)際上是
Node,而Node包括Element和Comment,CDATA_SECTION等很多種以及根節(jié)點(diǎn)Document類型,絕大多數(shù)我們僅關(guān)心Element,即實(shí)際控制頁面結(jié)構(gòu)的Node,其他類型的Node忽略即可 - 根節(jié)點(diǎn)
Document已經(jīng)自動綁定為全局變量document
- 更新DOM
- 方法1: 修改
innerHTML屬性,不僅僅可以修改一個(gè)DOM節(jié)點(diǎn)的文本內(nèi)容,還可以直接通過HTML片段修改DOM節(jié)點(diǎn)內(nèi)部的子樹 - 方法2: 修改
innerText或textContent屬性,可以自動對字符串進(jìn)行HTML編碼,保證無法設(shè)置任何HTML標(biāo)簽 - 區(qū)別:
innerText不返回隱藏元素的文本,而textContent返回所有文本,另外,IE<9不支持textContent - DOM節(jié)點(diǎn)的
style屬性對應(yīng)所有的CSS,可以直接獲取或設(shè)置,CSS允許font-size這樣的名稱,它并非JavaScript有效的屬性名,所以需要在JavaScript中改寫為駝峰式命名fontSize
// 獲取<p id="p-id">...</p> var p = document.getElementById('p-id'); // 設(shè)置CSS: p.style.color = '#ff0000'; p.style.fontSize = '20px'; p.style.paddingTop = '2em'; - 方法1: 修改
- 插入DOm
-
innerHTML可以插入DOM節(jié)點(diǎn),如果這個(gè)DOM節(jié)點(diǎn)不是空的,innerHTML會直接替換點(diǎn)原來的所有子節(jié)點(diǎn) -
appendChild插入一個(gè)子節(jié)點(diǎn)到父節(jié)點(diǎn) - insertBefore
parentElemnt.insertBefore(newElement,referenceElement);子節(jié)點(diǎn)會插入到referenceElement之前 -
insertBefore重點(diǎn)是要拿到一個(gè)參考子節(jié)點(diǎn)的引用,很多時(shí)候,需要循環(huán)一個(gè)父節(jié)點(diǎn)的所有子節(jié)點(diǎn),可以通過迭達(dá)children屬性實(shí)現(xiàn)
-
- 刪除DOM
- 刪除一個(gè)DOM比插入要容易的多
- 要刪除一個(gè)節(jié)點(diǎn),首先要獲得該節(jié)點(diǎn)本身以及它的父節(jié)點(diǎn),然后調(diào)用
removeChild把自己刪除
// 拿到待刪除節(jié)點(diǎn): var self = document.getElementById('to-be-removed'); // 拿到父節(jié)點(diǎn): var parent = self.parentElement; // 刪除: var removed = parent.removeChild(self); removed === self; // true- 刪除的節(jié)點(diǎn)雖不在文檔樹中,但它還在內(nèi)存中,
children屬性是一個(gè)只讀屬性,并且它在子節(jié)點(diǎn)變化時(shí)會實(shí)時(shí)更新 - 在刪除多個(gè)節(jié)點(diǎn)時(shí),要注意
children屬性時(shí)刻都在變化
三、操作表單
- 表單
- 用JavaScript操作表單和操作DOM類似,表單是特殊的DOM
- 常見的表單:
- 文本框,對應(yīng)的
<input type="text">,用于輸入文本 - 口令框,對應(yīng)的
<input type="password">,用于口令 - 單選框,對應(yīng)的
<input type="radio">,用于選擇一項(xiàng) - 復(fù)選框,對應(yīng)的
<input type="checkbox">,用于選擇多項(xiàng) - 下拉框,對應(yīng)的
<select>,用于選擇一項(xiàng) - 隱藏文本框,對應(yīng)的
<input type="hidden">,用戶不可見,提交表單時(shí)可以把隱藏文本發(fā)送到服務(wù)器
- 文本框,對應(yīng)的
-
input節(jié)點(diǎn)的引用,可以直接調(diào)用value獲得對應(yīng)的用戶輸入值 - 對于
radio和checkbox的value屬性返回的永遠(yuǎn)是HTML的預(yù)設(shè)值 - 更新值,直接改
value,而checkbox需要設(shè)置checked為true或fasle
- HTML5控件
- 新增大量標(biāo)準(zhǔn)控件,常用的包括
date,datetime,datetime-local,color等 - 不支持HTML5的瀏覽器無法識別新的控件,會被當(dāng)做
type="text"來顯示 - 支持HTML5的瀏覽器可以獲得格式的字符串
- 新增大量標(biāo)準(zhǔn)控件,常用的包括
- 提交表單
- 方式一:
<form>元素的submit()方法提交表單 - 方式二: 響應(yīng)
<form>本身的onsubmit事件,在提交form時(shí)作修改 - 安全起見,提交表單時(shí)一般不傳輸明文口令
- 方式一:
四、操作文件
- 上傳控件
- HTML表單中,可以上傳文件的唯一控件就是
<input type='file'> - 當(dāng)一個(gè)表單包含
<input type='file'>時(shí),表單enctype必須指定為multipart/form-data,method必須指定為post,瀏覽器才能正確編碼并以mutipart/form-data格式發(fā)送表單的數(shù)據(jù) - 出于安全考慮,瀏覽器只允許用戶點(diǎn)擊
<input type='file'>來選擇本地文件,用JavaScript對其value賦值是沒有效果的
- HTML表單中,可以上傳文件的唯一控件就是
- File API
- HTML5的API提供了
File和FileReader兩個(gè)主要對象,可以獲得文件信息并讀取文件
- HTML5的API提供了
- 單線程執(zhí)行模式
- 在JavaScript中,瀏覽器的JavaScript執(zhí)行引擎在執(zhí)行JavaScript代碼時(shí),總是以單線程模式執(zhí)行
- JavaScript處理多任務(wù),采用的是異步調(diào)用,由于是異步調(diào)用,無法知道什么時(shí)候操作結(jié)束,所以需要先設(shè)置一個(gè)回調(diào)函數(shù),但函數(shù)調(diào)用完畢時(shí),JavaScript引擎將自動調(diào)用我們設(shè)置的回調(diào)函數(shù)
五、Ajax
- Ajax定義
- Asynchronous JavaScript and XML 用JavaScript執(zhí)行異步網(wǎng)絡(luò)請求
- Web的運(yùn)作原理就是:一個(gè)Http請求對應(yīng)一個(gè)頁面
- 現(xiàn)代瀏覽器寫Ajax主要依靠
XMLHttpRequest對象,對于低版本的IE,需要換一個(gè)ActiveXObject對象 - 創(chuàng)建
XMLHttpRequest對象后,要先設(shè)置onreadystatechange的回調(diào)函數(shù),在回調(diào)函數(shù)中,通常只需通過readyState===4判斷請求是否完成,如果已完成,再根據(jù)status===200判斷是否是一成功的響應(yīng) -
XMLHttpRequest對象的open()方法有3個(gè)參數(shù),第一個(gè)參數(shù)指定是Get還是POST方式,第二參數(shù)指定URL地址,第三個(gè)參數(shù)指定是否使用異步,默認(rèn)為true(該參數(shù)不要只用為false,否則瀏覽器將停止響應(yīng),直到Ajax請求完成) -
send()方法才真正發(fā)送請求,Get請求不需要參數(shù),POST請求不需要參數(shù),POST請求需要把body部分以字符串或者FormData對象傳進(jìn)去
- 安全限制
- 默認(rèn)情況下,JavaScript在發(fā)送Ajax請求時(shí),URL的域名必須和當(dāng)前頁面完全一致(即域名要相同,協(xié)議要相同,端口要相同)
- 用JavaScript請求外域,可以使用Flash插件,或在同源域名下架設(shè)一個(gè)代理服務(wù)器來轉(zhuǎn)發(fā),JavaScript負(fù)責(zé)把請求發(fā)送到代理服務(wù)器,或使用JSONP方式(必須為GET請求,并要求返回JavaScript)
-
CORS是HTML5新的跨域策略,全稱Cross-Orign Resource Sharing,是HTML5規(guī)范定義的如何跨域訪問資源 -
Access-Control-Allow-Origin在返回的Access-Control-Allow-Origin包含本域,b本次請求就可以成功 - 是否跨域成功,取決于對方服務(wù)器是否愿意你設(shè)置一個(gè)正確的
Access-Control-Allow-Orign,決定權(quán)始終在對方手中 -
簡單請求包括GET、HEAD和POST(Post的Content-Type類型,僅限application/x-www-form-urlencoded,multipart/form-data和text/plain,并且不能出現(xiàn)任何自定義頭) - 對于
PUT、DELETE以及其他類型如application/json的POST請求,在發(fā)送Ajax請求之前,瀏覽器會先發(fā)送一個(gè)OPTIONS請求(成為preflighted請求)到這個(gè)URL上,詢問目標(biāo)服務(wù)器是否接受,服務(wù)器必須明確指出允許的Method,如:Access-Control-Allow-Methods:POST,GET,PUT,OPTIONS - 由于以
POST、PUT方式傳送JSON格式的數(shù)據(jù)在REST中很常見,所以要跨域正確處理POST和PUT請求,服務(wù)器必須正確響應(yīng)OPTIONS請求
六、Promise
- 定義
-
Promise有各種開源實(shí)現(xiàn),在ES6中被統(tǒng)一規(guī)范,由瀏覽器統(tǒng)一支持
`use strict`; function test(resolve, reject) { var timeOut = Math.random() * 2; console.log('set timeout to: ' + timeOut + ' seconds.'); setTimeout(function () { if (timeOut<1) { console.log('call resolve()...'); resolve('200 OK'); } else { console.log('call reject()...'); reject('timeout in ' + timeOut + ' seconds.'); } }, timeOut * 1000); } new Promise(test).then(function(result){ console.log('Success'+result); }).catch(function(result){ console.log('failure'+result); })- 成功執(zhí)行
then,失敗執(zhí)行catch -
Promise的最大好處是在異步執(zhí)行的流程中,把執(zhí)行代碼和處理結(jié)果的代碼清晰地分離 - 并行執(zhí)行任務(wù):
Promise.all() - 多個(gè)異步任務(wù)是為了容錯(cuò):
Promise.race()
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); Promise.race([p1, p2]).then(function (result) { console.log(result); // 'P1' }); //由于p1執(zhí)行較快,Promise()`then`將先獲得結(jié)果`p1`,`p2`仍在執(zhí)行,但執(zhí)行結(jié)果將被拋棄 * 組合使用Promise,可以將很多異步任務(wù)以并行和串行的方式組合起來執(zhí)行 -
七、Canvas
- Canvas用法
- HTML5新增的組件,類似一塊幕布,可以在JavaScript在上面繪制各種圖表、動畫等
- 一個(gè)Canvas定義了一個(gè)指定尺寸的矩形框,在這個(gè)框內(nèi)可以隨意繪制
<canvas id="test-canvas" width="300" height="200"></canvas> -
canvas.getContext來測試瀏覽器是否支持Canvas -
getContext('2d')方法讓我們拿到一個(gè)CanvasRenderingContext2D對象,所有繪圖操作都需要通過這個(gè)對象完成 - `getContext('webgl')方法 是可以使用WebGL規(guī)范,允許在Canvas中繪制3D圖形
- 基本繪制
- Canvas的坐標(biāo)系統(tǒng): Canvas的坐標(biāo)以左上角為原點(diǎn),水平向右為x軸,垂直向下為Y軸,以像素為單位,所以每個(gè)點(diǎn)都是非負(fù)數(shù)
-
CanvasRenderingContext2D對象有若干方法來繪制圖形 - Canvas可以繪制基本的形狀和文本,還可以實(shí)現(xiàn)動畫、縮放、各種濾鏡和像素轉(zhuǎn)換等高級操作
- 實(shí)現(xiàn)復(fù)雜操作,可以考慮以下優(yōu)化方案
- 通過創(chuàng)建一個(gè)不可見的Canvas來繪圖,然后將最終繪制結(jié)果復(fù)制到頁面的可見Canvas中
- 盡量使用整數(shù)坐標(biāo)而不是浮點(diǎn)數(shù)
- 可以創(chuàng)建多個(gè)重疊的Canvas繪制不同的層,而不是在一個(gè)Canvas中繪制非常復(fù)雜的圖
- 背景圖片如果不變可以直接用
<img>標(biāo)簽并放到最底層