DOM編程藝術(shù)

element.chidren和element.childNodes的區(qū)別

element.children是Element的屬性,所以它其中只包含element類型的節(jié)點(diǎn),而不包含文本類型的元素

element.childNodes是Node的屬性,所以它包含所有的子節(jié)點(diǎn),包括元素類型的節(jié)點(diǎn)和文本類型的節(jié)點(diǎn)

例如

var el=document.createElement("div");
el.textContent="foo"
el.childNodes.length===1;// TextNode is a node child
el.children.length===0;// no Element children


##獲取節(jié)點(diǎn)
- 父子關(guān)系
-ParentNode
-firstChild、lastChild、childNodes
- 兄弟關(guān)系
-previousSibling、nextSibling
-previousElementSibling、nextElementSibling
**但是這些訪問關(guān)系很不穩(wěn)定,一旦頁面結(jié)構(gòu)變化,可能會(huì)導(dǎo)致代碼不能用**

#### getElementById

element.getElementById(id) //返回一個(gè)Node元素

#### getElementsByTagName

collection = element.getElementsByTagName(TagName) //返回一個(gè)數(shù)組,可以通過下表訪問,這個(gè)集合是動(dòng)態(tài)的,如果頁面中的元素由于其他的操作被刪除或者增加,collection指向的內(nèi)容也會(huì)隨之變化

#### getElementsByClassName

collection = element.getElementsByClassName(ClassName Classname) // 返回一個(gè)數(shù)組,其中classname可以有多個(gè),切順序無所謂,返回同時(shí)有這些類名修飾的元素

**IE6、7、8不支持該屬性**

####querySelector/All

list = element.querySelector/All(selector)
//例如
var users = document.querySelector('#users') //按照id選擇
list = users.querySelectorAll(".user") //類選擇器,選擇所有類名包含user的
//等同于
list = document.querySelectorAll("#users .user") //但是list是非動(dòng)態(tài)的,所以當(dāng)其他操作更改了list選中的內(nèi)容后list的內(nèi)容是不會(huì)修改的


##創(chuàng)建節(jié)點(diǎn)
.createElement()

##修改節(jié)點(diǎn)
.textContent = "修改后的文本"
.innerText也經(jīng)常用到,但是不符合W3C標(biāo)準(zhǔn),且firefox不支持該屬性,textContent符合標(biāo)準(zhǔn),但是ie9以下版本不支持,所以為了兼容性,有時(shí)需要用特殊處理

##添加節(jié)點(diǎn)

element.appendChild(achild)
var achild = element.insertBefore(achild, referenceChild)


##刪除節(jié)點(diǎn)

element.removeChild(achild)
.innerHTML = "" //innerHTML包含的是包含標(biāo)簽在內(nèi)的所有內(nèi)容,直接將其內(nèi)容賦值為空串也可以起到刪除的作用


![刪除大段HTML代碼](http://upload-images.jianshu.io/upload_images/3770010-3ffca4613926cdc9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##屬性操作
dom對(duì)象實(shí)際上是一個(gè){}括起來的字典,所有的屬性都可以通過[]和點(diǎn)號(hào)來訪問。所有用屬性訪問器訪問到的屬性都是一個(gè)經(jīng)過轉(zhuǎn)換的實(shí)用對(duì)象。如下圖:獲取到的字符串會(huì)被轉(zhuǎn)換為String類型,數(shù)字會(huì)被轉(zhuǎn)換為Number類型,函數(shù)會(huì)被封裝到另一個(gè)函數(shù)中。

<input class="u-txt" maxlength="10" disabled onclick="showSuggest();">

input.attributeName

| attributeName | value | type | 
|:----------:|:--------:|:-------:|
| className | "u-txt" | String |
| maxLength | 10 | Number |
| disabled | true | Boolean |
| onclick | function onclick(event) {...} | Function |

例如一個(gè)輸入框?qū)?yīng)的dom對(duì)象是input。

####通過屬性訪問器讀寫
好處是可以訪問到一個(gè)使用對(duì)象,壞處是有些屬性的名字會(huì)有沖突需要單獨(dú)記憶
**** 注:由于某些css屬性名和js的關(guān)鍵字沖突,某些屬性的訪問名字需要特殊記憶,如:
類名:input.className
for屬性:input.htmlFor
等.......

input.value = "輸入的內(nèi)容" //就可以設(shè)置屬性
input["disabled"] = true //兩種訪問方式

####通過attribute讀寫
通過attribute讀寫不會(huì)存在屬性名和關(guān)鍵字沖突的問題,但是通過getAttribute操作得到的屬性都是字符串

input.getAttribute("attributeName")


| attributeName | value | type |
|:-------------------:|:-------:|:------:|
| class | "u-txt" | String |
| maxLength | "10" | String |
| disabled | "" | String |
| onclick | "showSuggest(); " | String |

var attribute = element.getAtrribute(String attributeName)
var attribute = element.setAttribute(String name, value)
//例如:
var attribute = input.getAttribute("class")
input.setAttribute("disabled", "") //只要disabled出現(xiàn)過,他就是disabled的,value無所謂,數(shù)字,布爾,字符串,都行


####通過dataset訪問
在屬性名前加data-符號(hào)即可,dataset一般是用來做自定義屬性的,如下圖

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3770010-5fc3a846eca73ae9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##樣式操作
####樣式訪問
css樣式表中的內(nèi)容可以通過js進(jìn)行動(dòng)態(tài)的修改,其中,外部引入的文件以及被<style>標(biāo)簽圍繞的樣式是通過element.sheet訪問的,而標(biāo)簽內(nèi)部的style屬性包圍的值對(duì)應(yīng)的js是element.style。
例如

<style>
body{margin: 30}
p{color:#aaa; line-height: 20px;}
</style>

element.sheet.cssRules[1].style //{color: #aaa, line-height: 20px}, 類型是CSSStyleDeclaraiton的類
element.sheet.cssRules[1].selectorText //p
element.sheet.cssRules[1].style.lineHeight //line-height

內(nèi)部樣式訪問中

element.style.lineHeight //element.style同樣是一個(gè)CSSStyleDeclaration

以上的訪問方式的缺陷在于,屬性名和css中的名字不完全一樣,使用上不是很方便,因此,

element.style.cssText = "border-color: red; color: #bbb"; //也是一種訪問方式,可以直接修改css內(nèi)部的文本

好的編程習(xí)慣要求盡量不在代碼邏輯中修改css,因此如果要對(duì)元素的樣式進(jìn)行修改,一般建議事先在css中寫好另外一種樣式,并在通過修改類的方法來修改樣式,如,

element.className += "another_class" //會(huì)自動(dòng)覆蓋其他的樣式

而如果要對(duì)大量元素進(jìn)行替換,如要修改整個(gè)頁面的樣式和風(fēng)格,可以直接更改應(yīng)用于本頁面的css文件,如

<link id = "skin" rel="stylesheet" href="css/skin1.css">

document.getElementById("skin").href = "css/skin2.css" //對(duì)整個(gè)頁面的css文件進(jìn)行了替換

####樣式獲取
即如何獲取實(shí)際樣式,顯然element.style是不行的,因?yàn)槿绻貨]有內(nèi)前樣式的話,這種方式是不能獲取到實(shí)際樣式值,本標(biāo)題指的是如何獲取實(shí)際樣式的值

var style = window.getComputedStyle(element [,pseudoElt]);
//返回的是一個(gè)CSSStyleDeclaration的類,但是是一個(gè)只讀屬性,不可以改,但獲取到的確實(shí)是一個(gè)元素的實(shí)際屬性,pseudoElt屬性一般不常用


##事件
事件有一個(gè)事件流的概念,控制的時(shí)間的發(fā)生順序,事件流分為3個(gè)階段

![事件流](http://upload-images.jianshu.io/upload_images/3770010-43f9b281c762a0a9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

1.capture(捕獲階段)
2.target(目標(biāo)階段)
3.upward(回溯階段)
具體見
([http://www.w3.org/TR/uievents/#dom-event-architecture](http://www.w3.org/TR/uievents/#dom-event-architecture) )
####事件的注冊(cè)

eventTarget.addEventListener(type, listener[, useCapture])
//第一個(gè)是事件類型,如點(diǎn)擊,hover等,第二個(gè)是監(jiān)聽器,即事件觸發(fā)后要調(diào)用的函數(shù),第三個(gè)參數(shù)可選,是一個(gè)布爾值,當(dāng)為false時(shí),回調(diào)函數(shù)在upward階段觸發(fā),當(dāng)為true時(shí),回調(diào)函數(shù)在capture階段觸發(fā),默認(rèn)值為false。useCpature的直觀表現(xiàn)就是控制先觸發(fā)父元素的事件還是先觸發(fā)子元素的時(shí)間
//當(dāng)事件為點(diǎn)擊事件的時(shí)候,也可以eventTarge.onclick = listener來注冊(cè),但是如此注冊(cè)則只能有一個(gè)監(jiān)聽器,不可以有多個(gè)。


####事件取消注冊(cè)

eventTarget.addEventListener(type, listener[, useCapture])


####事件觸發(fā)
1. 事件發(fā)生觸發(fā)
2. 代碼觸發(fā)

eventTarget.dispatchEvent(type)


####事件對(duì)象
事件對(duì)象指的是當(dāng)一個(gè)時(shí)間被觸發(fā)的時(shí)候,listener有一個(gè)參數(shù)為event會(huì)被傳入,event中包含事件的一些相關(guān)信息,如點(diǎn)擊事件鼠標(biāo)的坐標(biāo),鍵盤中shift是否被按下等信息,event被稱為事件對(duì)象。
*注意:在ie9以下的ie版本中,event不是被傳入的,而是保存在window.event中,因此需要如下代碼來做兼容*

event = event || window.event

事件對(duì)象有些屬性和方法
屬性:
- 繼承了UIEvent的所有屬性
- type //事件類型,如點(diǎn)擊事件等等

type = event.type

- targets(srcElement)//目標(biāo)節(jié)點(diǎn),即觸發(fā)事件的標(biāo)簽 ,ie低版本中屬性名為srcElement,其他瀏覽器為targets
- currentTarget //當(dāng)前事件位于哪個(gè)標(biāo)簽

targets = event.targets || event.srcElement

方法:
- stopPropagation //阻止事件繼續(xù)傳播

event.stopPropagation()

- preventDefault //阻止默認(rèn)事件,如點(diǎn)擊a標(biāo)簽會(huì)默認(rèn)進(jìn)行頁面跳轉(zhuǎn),如果要阻止默認(rèn)事件,而僅僅是調(diào)用listener,則需要調(diào)用這個(gè)方法

event.preventDefault()

- stopImmediatePropagation //不僅阻止事件繼續(xù)傳播,也中斷了當(dāng)前節(jié)點(diǎn)后續(xù)監(jiān)聽器的觸發(fā),即如果當(dāng)前節(jié)點(diǎn)注冊(cè)了多個(gè)監(jiān)聽器,則之后的監(jiān)聽器也不再執(zhí)行

event.stopImmediatePropagation()


####事件分類(type)
![事件分類](http://upload-images.jianshu.io/upload_images/3770010-6bcae3a62817b62a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
其中,WheelEvent繼承自鼠標(biāo)事件,是滾輪事件。這些事件中最常用的就是鼠標(biāo)事件

######事件
| 事件類型 | 觸發(fā)場景 | 是否冒泡 | 元素 | 默認(rèn)事件 | 例子      | 
|:------------:|:------------:|:------------:|:------:|:------------:|:----------:|
| load | 當(dāng)一個(gè)元素加載完成時(shí),如window、image等 | NO | window\document\element | None | window\iframe\image
| unload | 當(dāng)頁面退出時(shí) | NO | window\document\element | None | window |
| error | 報(bào)錯(cuò),如設(shè)置了錯(cuò)誤的url等| NO | window\document\element | None | window\image |
| select | 內(nèi)部元素被選中時(shí) | NO | element | None | input\textarea |
| abort | 加載被終止 |  NO | window\document\element | None | window\image |

######UI事件(UIEvent)
| 事件類型 | 觸發(fā)場景 | 是否冒泡 | 元素 | 默認(rèn)事件 | 例子      | 
|:------------:|:------------:|:------------:|:------:|:------------:|:----------:|
| resize | 修改窗體大小時(shí) | NO | window\element | None | window\iframe
| scroll | 頁面發(fā)生滾動(dòng) | 當(dāng)元素scroll時(shí)YES,當(dāng)瀏覽器滾動(dòng)時(shí)NO | window\element | None | document\div |

######鼠標(biāo)事件(MouseEvent)
鼠標(biāo)事件類型:
click:鼠標(biāo)點(diǎn)擊并松開后觸發(fā)
dbclick:雙擊后觸發(fā)
mousedown:鼠標(biāo)鍵按下
mouseup:鼠標(biāo)鍵松開
mousemove:鼠標(biāo)移動(dòng)
mouseenter:當(dāng)鼠標(biāo)進(jìn)入某個(gè)元素A時(shí),A會(huì)觸發(fā)該事件,但是當(dāng)鼠標(biāo)再次從A進(jìn)入A的子元素時(shí),不會(huì)再次出發(fā)
mouseleave:與enter對(duì)應(yīng),鼠標(biāo)離開某個(gè)元素A時(shí)觸發(fā),但是當(dāng)鼠標(biāo)進(jìn)入A的子元素時(shí),不會(huì)觸發(fā),因?yàn)橄氲接诖藭r(shí)鼠標(biāo)仍然處于A的內(nèi)部
mouseover:功能與mouseenter類似,但是會(huì)級(jí)聯(lián)觸發(fā),即當(dāng)一個(gè)元素觸發(fā)mouseover事件時(shí),該元素的所有祖先元素也會(huì)觸發(fā)over。因此,當(dāng)鼠標(biāo)從A中移到A的子元素 或 從A的子元素移到A都會(huì)觸發(fā)mouseover
mouseout:與mouseleave類似,但是會(huì)級(jí)聯(lián)觸發(fā),與mouseover相對(duì)應(yīng),即當(dāng)一個(gè)元素觸發(fā)mouseout時(shí),它的所有祖先元素都會(huì)觸發(fā)這個(gè)事件。

event.clientX, event.client.Y //鼠標(biāo)距離瀏覽器最左、上端的距離
event.screenX, event.screenY//鼠標(biāo)距離屏幕最左、上端的距離
event.ctrlKey, event.shiftKey, event.altKey, event.metaKey //鼠標(biāo)事件觸發(fā)時(shí)是否同時(shí)有鍵盤上的一些按鍵被按下,類型為boolean。其中metaKey在Windows上代表“Win鍵”,在Mac上代表“command鍵”
event.button //值為0,1,2分別代表鼠標(biāo)按下的左、中、右鍵,4,5代表瀏覽器的前進(jìn)和后退鍵,即部分鼠標(biāo)擁有的側(cè)面的按鍵

鼠標(biāo)事件的觸發(fā)順序:
1.當(dāng)鼠標(biāo)從A元素上方經(jīng)過
mousemove(A的某祖先元素) -> mouseover(A) -> mouseenter(A) -> mousemove(A) -> mouseout(A) -> mouseleave(A)
2.當(dāng)鼠標(biāo)在A中點(diǎn)擊
mousedown -> mouseup -> mouseclick

######焦點(diǎn)事件(FocuseEvent)
| 事件類型 | 是否冒泡 | 元素 | 默認(rèn)事件 | 元素例子 | 何時(shí)觸發(fā) |
|:------------:|:------------:|:------:|:------------:|:------------:|:------------:|
| blur | NO | Window\Element | None | window\input | 失去焦點(diǎn)時(shí) |
| focus | NO | Window\Element | None | window\input | 獲得焦點(diǎn)時(shí) | 
| focusin | YES | Window\Element | None | window\input | 即將獲得焦點(diǎn)時(shí) |
| focusout | YES | Window\Element | None | window\input | 即將失去焦點(diǎn)時(shí) |
*“冒泡”指的是是否會(huì)級(jí)聯(lián)觸發(fā),即當(dāng)一個(gè)元素觸發(fā)該事件時(shí),其祖先元素會(huì)不會(huì)觸發(fā)該事件*
*后兩個(gè)主要就是在blur和focus被觸發(fā)前會(huì)率先觸發(fā)*

事件屬性:
- 繼承了UIEvent的所有屬性
- relatedTarget:當(dāng)一個(gè)元素失去焦點(diǎn)時(shí),會(huì)有另外一個(gè)獲得焦點(diǎn),反之亦然。此時(shí),獲得焦點(diǎn)和失去焦點(diǎn)的這兩個(gè)元素互為relatedTarget

######輸入事件(InputEvent)
事件類型
- beforeInput:指敲擊鍵盤后,輸入的內(nèi)容還沒顯示出來時(shí)觸發(fā)的事件
- Input:指敲擊鍵盤后,輸入的內(nèi)容已經(jīng)顯示出來時(shí)觸發(fā)的事件

######鍵盤事件(KeyboardEvent)
事件類型
- keydown
- keyup
屬性
- 繼承的屬性
- key:按下什么鍵盤,String類型,按鍵類型,如:數(shù)字鍵,控制鍵等
- code:按鍵碼,String類型
- ctrlKey、altKey、metaKey、shiftKey:布爾型,這些鍵是否被按下
- repeat:某個(gè)鍵是否一直按著不放

####事件代理

<ul>
<li></li>
<li></li>
<li></li>
</ul>

例如上述代碼,如果所有的li都具有相同的事件和事件處理過程,我們逐個(gè)為標(biāo)簽注冊(cè)監(jiān)聽器,一個(gè)方便的方法是只為ul注冊(cè)監(jiān)聽器而不管li,因?yàn)楹芏嗟氖录紩?huì)冒泡,因此同樣的事件如果在li上觸發(fā)了,那么也會(huì)在ul上觸發(fā)。這個(gè)方法稱為事件代理
- 好處:減少代碼,方便修改 
- 壞處:當(dāng)一個(gè)父元素有太多的監(jiān)聽器要處理時(shí),會(huì)使得代碼難以維護(hù),如理論上所有會(huì)冒泡的事件都可以掛在window上,通過代理來觸發(fā),但是這顯然不是一個(gè)好的決定

##數(shù)據(jù)通信
網(wǎng)頁的請(qǐng)求是先由瀏覽器發(fā)送一個(gè)請(qǐng)求到服務(wù)器(請(qǐng)求報(bào)文),然后服務(wù)器再返回內(nèi)容給瀏覽器,然后瀏覽器將內(nèi)容顯示出來。
####請(qǐng)求報(bào)文格式
1.頭行
- 請(qǐng)求方法
- 主體地址
- http版本

2.頭部
- Accept:http接受的媒體類型
- Accept-Encoding:媒體類型的編碼方式
- Accept-Language:瀏覽器端可以接受的語言
- Cache-Control:緩存策略
- Cookie:想服務(wù)器發(fā)送的cookie內(nèi)容
- User-Agent:瀏覽器的名詞和版本


3.請(qǐng)求體
GET方法請(qǐng)求體為空

####響應(yīng)報(bào)文格式
1.頭行
- HTTP版本
- 狀態(tài)碼
- 狀態(tài)碼描述

2.頭部
- Server:服務(wù)器端的服務(wù)器是哪種服務(wù)器

3.相應(yīng)內(nèi)容
請(qǐng)求獲得的內(nèi)容主題

####請(qǐng)求方法
| 方法 | 描述 | 是否含有主體 |
|:-------:|:-------:|:-----------------:|
| get | 獲取一份文檔 | NO |
| post | 發(fā)送需要處理的數(shù)據(jù) | YES |
| put | 將請(qǐng)求的主體部分存儲(chǔ)在服務(wù)器上 | YES |
| delete | 刪除一份文檔 | NO |
| TRACE | 對(duì)報(bào)文進(jìn)行追蹤| NO |
| OPTIONS | 決定可以在服務(wù)器上執(zhí)行哪些方法 | NO |
| HEAD | 只獲取文檔的頭部 | NO |

####URL構(gòu)成
protocol://host/pathname ? search # hash

例如:
http://www.163.com:8080/index.html?r=admin#news


####HTTP版本
目前廣泛使用的是http 1.1版本

####HTTP狀態(tài)碼
| 狀態(tài)碼 | 狀態(tài)嗎描述 | 含義 |
|:---------:|:---------------:|:-----------:|
| 200 | OK | 一般用于響應(yīng)GET和POST方法 | 
| 301 | Moved Permanently | 請(qǐng)求的資源已經(jīng)轉(zhuǎn)移,瀏覽器會(huì)自動(dòng)跳轉(zhuǎn) |
| 304 | Not Modified | 所請(qǐng)求的數(shù)據(jù)未修改,瀏覽器讀取緩存 | 
| 400 | Bad Request | 請(qǐng)求語法錯(cuò)誤,服務(wù)器無法理解 |
| 404 | Not Found | 資源未找到 | 
| 500 | Internal Server Error | 服務(wù)器內(nèi)部錯(cuò)誤 | 

####Ajax
通信流程
1. 創(chuàng)建一個(gè)XHR對(duì)象,包含3個(gè)關(guān)鍵屬性
 - readyState
 - status
 - responseText
剛創(chuàng)建時(shí),readyState的值為1

var xhr = new XMLHttpRequest()

2. 調(diào)用open()方法,此時(shí)readyState變?yōu)?,調(diào)用時(shí)會(huì)定義請(qǐng)求的方法,請(qǐng)求的內(nèi)容等等

xhr.open(method, url[ ,async = true]) //method是請(qǐng)求方法,如get、post等,url是請(qǐng)求地址,async表示開啟一個(gè)異步請(qǐng)求,默認(rèn)為true
xhr.sendRequestHeader( header, value) //也可以不設(shè)置

3. 調(diào)用send()方法,此時(shí)readyState變?yōu)?, 開始像服務(wù)器發(fā)送請(qǐng)求

xhr.send([data = null]) // 發(fā)送一個(gè)請(qǐng)求
//當(dāng)使用post方法時(shí),請(qǐng)求參數(shù)就通過data傳入,如果是get方法,則請(qǐng)求字符串在open時(shí)url中設(shè)置

4. 服務(wù)器端返回?cái)?shù)據(jù),此時(shí)readyState變?yōu)?,status變?yōu)榉祷氐臓顟B(tài)碼,如200,responsText變?yōu)檎?qǐng)求得到的內(nèi)容

> **同源策略**
> 如果兩個(gè)頁面具有相同的協(xié)議,主機(jī),端口,那么兩個(gè)頁面則同源。同一個(gè)源內(nèi)的網(wǎng)頁在訪問時(shí)url都是用的是相對(duì)地址

> **跨域資源的訪問**
> Frame代理,JSONP代理等
> Frame代理資料 [https://github.com/genify/nej/blob/master/doc/AJAX.md](https://github.com/genify/nej/blob/master/doc/AJAX.md)
> CORS:[http://www.w3.org/TR/cors/](http://www.w3.org/TR/cors/)

##數(shù)據(jù)存儲(chǔ)
####cookie
形式:鍵值對(duì)
屬性:

| 屬性名 | 默認(rèn)值 | 作用域 | 
|:---------:|:---------:|:---------:|
| name | | 名 | 
| value | | 值 |
| Domain | 當(dāng)前文檔域 | 作用域 |
| Path | 當(dāng)前文檔路徑 | 作用路徑 |
| Expries/Max-age | 瀏覽器會(huì)話時(shí)間 | 失效時(shí)間 |
| Secure | false | http協(xié)議時(shí)生效 | 
作用域和作用路徑對(duì)應(yīng)url中的域名和路徑名,例如:當(dāng)域名為163.com時(shí),則訪問163.com之下的所有域名都會(huì)攜帶此cookie,路徑名也相同,當(dāng)路徑名為/learn時(shí),則訪問該路徑以及其所有子路徑都會(huì)攜帶此cookie

cookie的設(shè)置和修改

document.cookie = 'name = value; secure = false';
//或者
function setCookie(name, value, domain, path, expires, secure){
var cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
if(expries)
cookie += '; expires = ' + expries.toGMTString();
if(path)
cookie += '; path = ' + path;
if(domain)
cookie += '; domain = ' + domain;
if(secure)
cookie += '; secure = ' + secure;
document.cookie = cookie;
}

cookie的刪除
- 指定cookie的max-age屬性設(shè)置為0即可

Cookie的缺陷
- 明文傳遞,缺乏安全性
- 不同的網(wǎng)頁跳轉(zhuǎn)時(shí)可能會(huì)攜帶cookie,會(huì)產(chǎn)生巨大的流量
- 大小限制,瀏覽器對(duì)cookie的大小都會(huì)有限制,一般為4kb左右,所以傳輸內(nèi)容有限

由于以上缺陷,目前很多網(wǎng)頁使用Storage來替代cookie

####Storage
分為localStorage和SessionStorage兩種。

######localstorage
作用域由協(xié)議,主機(jī)名,端口三個(gè)參數(shù)來確定。同一個(gè)瀏覽器內(nèi)多個(gè)窗口可以共享
######sessionStorage
作用域由協(xié)議,主機(jī)名,端口,窗口來確定,也就是說sessionStorage的作用域由一個(gè)窗口獨(dú)享而不能延伸到同一個(gè)瀏覽器的其他窗口

大小一般為5MB左右,由于要在內(nèi)存中存放,一般不建議開放過大

######JS接口
讀取:localStorage.name
添加修改:localStorage.name = "aaa"
刪除:delete localStorage.name
localStorage.length //鍵值對(duì)的數(shù)量
localStorage.getItem("name"), localStorage.key(i) //name是鍵值,i是索引,區(qū)間是0~length-1
localStorage.setItem("name", "aaa")
localStorage.removeItem("name")
localStorage.clear() //清空所有內(nèi)容


##JS動(dòng)畫
JS動(dòng)畫三要素
- 對(duì)象:dom對(duì)象,即“誰在動(dòng)”
- 屬性:即dom對(duì)象的屬性,如寬高、背景顏色、透明度等等
- 定時(shí)器:如setInterval、setTimeout、requestAnimationFrame等,可以利用定時(shí)器不斷的改變對(duì)象的屬性,從而實(shí)現(xiàn)動(dòng)畫的效果


1. setInterval

var intervalID = setInterval(func, delay[, para1, para2, ...])//設(shè)置動(dòng)畫
//func參數(shù)是一個(gè)函數(shù),delay規(guī)定func執(zhí)行的時(shí)間間隔,后面的參數(shù)是傳遞給func函數(shù)的參數(shù)
clearInterval(intervalID)//清除動(dòng)畫


2. setTimeout

var timeoutID = setTimeout(func[, delay, para1, para2, ...])
//setTimeout函數(shù)只執(zhí)行一次,delay表示從何時(shí)開始執(zhí)行,默認(rèn)立即執(zhí)行


3. requestAnimationFrame

var requestID = requestAnimationFrame(func) //不用設(shè)置間隔時(shí)間
cancelAnimationFrame(requestID) //清除動(dòng)畫
//這個(gè)函數(shù)沒有間隔時(shí)間這個(gè)選項(xiàng),由瀏覽器自己控制時(shí)間,間隔和顯示器的刷新一幀的時(shí)間相等,顯示器每刷新一次,func執(zhí)行一次,這樣的動(dòng)畫效果一般會(huì)更加流暢


##音頻與視頻

![視頻音頻、圖形](http://upload-images.jianshu.io/upload_images/3770010-a44f6428be5e730d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
video和audio標(biāo)簽非常像,但是由于video一般用于視頻,所以需要指定寬高,而audio不需要,除此之外,兩個(gè)標(biāo)簽的屬性基本上都一樣

<audio>
<source src="music.mp3" type="audio/mpeg">
<source src="music.wav" type="audio/x-wav">
<source src="music.ogg" type="audio/ogg">
</audio>

<video>
<source src="movie.mp4" type="video/mp4; codecs='avc1.42E01E, mp4.a.40.2'">
<source src="movie.webm" type="video/webm; codecs='vp8, vorbis'">
</video>

var a = new Audio();
a.canPlayType('audio/nav')//可以用來檢測瀏覽器是否支持這種audio格式,如果不支持,則返回空串,否則返回“probaly或者maybe”


####<video>和<audio>的屬性

| 屬性名 | 是否必須 | 默認(rèn)值 | 音頻文件的URL |
|:---------:|:------------:|:-----------:|:-------------------:|
| src | 是 | | 音頻文件的URL |
| controls | 否 | false | 是否向用戶顯示控件 |
| autoplay | 否 | false | 是否自動(dòng)播放 |
| preload | 否 | none | 可取值為none, metadata, auto。none是不預(yù)加載,metadata是只加載源信息,不加載資源,auto是自動(dòng)加載資源。音頻在頁面加載時(shí)預(yù)加載,并準(zhǔn)備播放,如果設(shè)置了autoplay,則忽略此屬性 |
| loop | 否 | false | 音頻結(jié)束時(shí)是否循環(huán)播放 | 

####視頻音頻的JS接口
load() //加載資源
play() //開始播放
pause() //暫停
muted //是否靜音
volume //音量,0——1之間的浮點(diǎn)數(shù)
playbackRate //播放速度,恒正,正常速度為1
currentTime //當(dāng)前時(shí)間,單位為s
**前三個(gè)為方法,后面4個(gè)位屬性,以上屬性都是可以修改值的**

paused //文件是否暫停
seeking //是否正在發(fā)生跳轉(zhuǎn)
ended //是否播放完成
duration //媒體總時(shí)長
initialTime //默認(rèn)起始播放時(shí)間
**以上屬性都是只讀屬性**

loadstart //開始請(qǐng)求媒體內(nèi)容
loadmetadata //已經(jīng)加載完成了源信息
canplay //已經(jīng)加載了一些內(nèi)容,可以開始播放了
play //調(diào)用了play()方法,或者設(shè)置了自動(dòng)播放并已加載完資源
waiting //緩沖數(shù)據(jù)不夠,播放暫停
playing //正在播放
**以上都是可以監(jiān)聽的事件,一共有12個(gè)事件可以監(jiān)聽,以上只是一部分**

####canvas

<canvas id="aCanvas" width="300px" height="150px"></canvas>

var canvas = document.getElementById("aCanvas")
var ctx = canvas.getContent('2d') //獲取一個(gè)渲染上下文的對(duì)象
ctx.globalCompositeOperation = “source-in”
//globalCompositeOperation的的屬性值是一個(gè)字符串,可選值見下圖,表示畫布上的多個(gè)內(nèi)容被繪制時(shí)的顯示內(nèi)容。下圖中,藍(lán)色正方形先畫,紅色的圓形后話,不同的屬性值分別可以確實(shí)他們的交疊次序,顯示互相的交集補(bǔ)集等


![組合操作](http://upload-images.jianshu.io/upload_images/3770010-d314fb7fa2d835c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##BOM(Browser Object Model)
廣義上來講,JS包含三個(gè)部分:
ECMAScript:即狹義的JS,也就是JS的語法等內(nèi)容
DOM(Document Object Model):已經(jīng)學(xué)習(xí)過,是前端JS進(jìn)行文檔內(nèi)容操作的接口,頂層對(duì)象為window.document
BOM:BOM包含DOM以及history, location, navigator等一些屬性和方法,BOM的頂層對(duì)象是window

*分了三個(gè)部分,是因?yàn)?,雖然從所屬關(guān)系來講,document屬于window,但是W3C對(duì)于document的一系列內(nèi)容都是有標(biāo)準(zhǔn)規(guī)定的,而window由于是瀏覽器相關(guān),并沒有統(tǒng)一的標(biāo)準(zhǔn),所以由瀏覽器廠商自行決定其接口等內(nèi)容*

![BOM和DOM的包含關(guān)系](http://upload-images.jianshu.io/upload_images/3770010-2f3ae0034edc4f5f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

| 屬性名 | 描述 | 
|:---------:|:---------:|
| navigator | 瀏覽器信息,包含瀏覽器版本,內(nèi)核版本,瀏覽器運(yùn)行平臺(tái)等諸多信息 |
| location | 瀏覽器定位和導(dǎo)航,包括端口,協(xié)議,主機(jī)地址,路徑等諸多地址 |
| history | 窗口瀏覽器歷史,僅記錄本窗口中的瀏覽歷史|
| screen | 屏幕信息,包括屏幕寬高、色域等 |

####location的方法

location.replace(url) //跳轉(zhuǎn)到另一個(gè)網(wǎng)頁,不記錄瀏覽歷史
location.assign(url) //跳轉(zhuǎn)到另一個(gè)網(wǎng)頁,記錄瀏覽歷史
location.reload(url) //重載本頁面


####history

history.go( Number length) //有一個(gè)參數(shù),可正可負(fù),代表將網(wǎng)頁前進(jìn)或者后退幾步
history.back() //網(wǎng)頁后退一步,沒有參數(shù),等同于history.go(-1)
history.forward() //網(wǎng)頁前進(jìn)一步,沒有參數(shù),等同于history.go(1)


####window下的一些方法
| 方法名 | 描述 |
|:---------:|:-------:|
| alert(), comfirm(), prompt() | 三種對(duì)話框 |
| setInterval(), setTimeout() | 計(jì)時(shí)器 |
| open(), close() | 打開新窗口,關(guān)閉窗口 |
window.open(url, name, String attr) //url是新窗口的地址,name是給新窗口起一個(gè)名字,attr是一個(gè)字符串,是新建窗口的一些屬性,如寬高等

####window下的一些事件
| 事件 | 描述 |
|:-------:|:---------:|
| load | 文檔和所有資源加載完畢時(shí)觸發(fā) |
| unload | 離開文檔前 | 
| beforeunload | 和unload類似,但它提供詢問用戶是否離開的機(jī)會(huì) |
| resize | 拖動(dòng)改變?yōu)g覽器大小時(shí) |
| scroll | 拖動(dòng)滾動(dòng)瀏覽器時(shí) | 

##表單操作

<form method=“post” action="url" enctype="xxxxx">
<fieldset>
<legend>標(biāo)題</legend>
<p><label></label><input></p>
<input required>
</fieldset>
</form>



![fieldset](http://upload-images.jianshu.io/upload_images/3770010-9897b108ecd2d43d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

表單中的數(shù)據(jù)需要傳送到服務(wù)器以便處理,每一個(gè)表單中的數(shù)據(jù)都是name:value鍵值對(duì),所以每個(gè)被提交的數(shù)據(jù)都應(yīng)該有name和value,當(dāng)然,默認(rèn)輸入框中的內(nèi)容也就是input標(biāo)簽的value值

form標(biāo)簽是表單的核心,它的可以設(shè)置的屬性有
name,target,method,autocomplete,accept-charset,action,enctype,novalidate等

####name
var form1 = document.forms.name
即只要寫出name就可以直接獲取到表單

####autocomplete
值為一個(gè)字符串,可以是“on”或者“off”,若是on的話,輸入框被點(diǎn)擊時(shí)被給一些輸入提示,提示源有可能是之前的填寫歷史等

####elements
form標(biāo)簽外的元素如果申明的form屬性,則這個(gè)標(biāo)簽雖然在空間上獨(dú)立于form之外,但是在功能上卻隸屬于form。
form的elements包含的內(nèi)容就包括form的子元素或者form外部隸屬于form的元素(除了所有的圖片元素),即<input type="image"/>標(biāo)簽不會(huì)被囊括在elements中

<form name = “ff” id="f">
<p><label><input name="a"/></label></p>
</form>
<p name="b" form="f"><label><input/></label></p>

var form1 = document.forms.ff
ff[name]
ff[index]
ff.elements[name]
ff.elements[index]
//以上4個(gè)方法都可以訪問表單元素的內(nèi)容


####form[name]

ff['a'] //注意??!此處可以返回id或者name為a的元素,而如果取到的內(nèi)容為空,則返回name或者id為a的img元素,即優(yōu)先返回非img元素
//如果有多個(gè)同名的元素,則返回的是一個(gè)動(dòng)態(tài)集合
//一旦用form[name]取過某個(gè)標(biāo)簽,即使這個(gè)標(biāo)簽改名了,依然可以用原名字來取,而form.elements[name]卻必須使用新的名字來取


####form.reset()
可以被reset的控件有keygen,input,output,select,textarea
reset的時(shí)候會(huì)觸發(fā)reset事件,但不會(huì)觸發(fā)change和input事件
如<input type="file">如果選擇了錯(cuò)誤文件想重新選擇,可以使用reset方法來重置,對(duì)于一般的input標(biāo)簽,input.value=''和reset方法基本結(jié)果一致,但是type為file的input標(biāo)簽不可以通過操作value來重置

####htmlFor

<form>
<input type="file" id="file1" hidden>
</form>
<label for="file1"></label>

當(dāng)然,for標(biāo)簽關(guān)聯(lián)的必須是可關(guān)聯(lián)元素,可關(guān)聯(lián)元素有button, fieldset, input, keygen, label, object, output, select, textarea

####input type=“file”
當(dāng)選擇為文件時(shí),屬性可以有
accept:可以接受的文件類型,類型指定方式
- audio/\*,video/\*,image/\*
- 指定以點(diǎn)號(hào)開頭的后綴名,如.mp3
- 使用MIME-type
- 多中類型的話需要都好分割
例如<input type="audio/*, .mp3">

multiple:可以選擇多個(gè)文件

####select

<select>
<option></option>
<optgroup>
<option></option>
<option></option>
</optgroup>
</select>

######select屬性
name:選項(xiàng)名稱
value:選項(xiàng)的值
multiple:控制是否可以多選
options:所有選項(xiàng)的集合,動(dòng)態(tài)集合
selectedOptions:所有選中的選項(xiàng)集合,動(dòng)態(tài)集合
selectedIndex:第一個(gè)選中的選項(xiàng)的索引,沒有則返回-1
add(element[, before]):添加一個(gè)選項(xiàng)
remove([index]):刪除某個(gè)選項(xiàng)

######optgroup屬性
disabled:表示這個(gè)組中的所有選項(xiàng)不可選
label:表示這個(gè)組為必選項(xiàng)

######option屬性
disabled和label,同optgroup
value:option的值
text:顯示的文本
index:option的索引
selected:已經(jīng)被選中
defaultSelected:默認(rèn)選中

######創(chuàng)建選項(xiàng)
documen.createElement("option")
new Option([text[, value[, defaultSelected[, selected]]]])

######添加選項(xiàng)
selectNode.add(toAdded, reference) //selectNode是select節(jié)點(diǎn)類
select.insertBefore(toAdded, reference) //select.insertBefore是一個(gè)接口,select不是節(jié)點(diǎn)類

######刪除選項(xiàng)
selectNode.removeChildI(optionNode)
select.remove(index)

####表單驗(yàn)證
可驗(yàn)證的表單有button, select, textarea, input
以下情況這些元素也不會(huì)驗(yàn)證
- input的標(biāo)簽的類型設(shè)置為了reset, button或者h(yuǎn)idden
- button標(biāo)簽的類型設(shè)置為了reset和button
- input和textarea標(biāo)簽的屬性設(shè)置了readonly
- 作為datalist的子孫節(jié)點(diǎn)
- disabled

######驗(yàn)證涉及到的接口element.
- willValidata:表示這個(gè)元素是否會(huì)在提交時(shí)被驗(yàn)證,布爾型
- checkValidity():驗(yàn)證一個(gè)元素,通過驗(yàn)證返回true,否則觸發(fā)invalid事件
- validity:存儲(chǔ)驗(yàn)證的結(jié)果
- validationMessage:用于顯示驗(yàn)證異常的信息
- setCustomValidity(message):用來自定義驗(yàn)證異常的信息

######隱式提交
即不通過點(diǎn)擊提交按鈕,而是通過回車鍵提交,隱式提交的情況有兩種
- 表單中有非禁用的提交按鈕
- 表單中沒有提交按鈕,但是表單中不超過一個(gè)類型為text, search, url, email, password, data, time, number的input元素

######提交過程
1. 瀏覽器根據(jù)enctype構(gòu)建指定的數(shù)據(jù)結(jié)構(gòu)
2. 從form中找出要提交的數(shù)據(jù)
3. 將數(shù)據(jù)按照指定數(shù)據(jù)結(jié)構(gòu)組織并提交

######編碼方式enctype
可選值為
application/x-www-form-urlencoded //默認(rèn),url方式,形式如:name=value&name2=value2
multipart/form-data //形式如:字符流,文件一般用這種編碼方式
text/plain //形式如:name=value name2=value。中間使用回車符分割,一般用于給人閱讀

######無刷新表單提交

<iframe name="iframe1">

</iframe>
<form target="iframe1">

</form>

iframe標(biāo)簽用來在其中嵌套另外一個(gè)穩(wěn)定,實(shí)現(xiàn)局部的更新,當(dāng)form的目標(biāo)指向一個(gè)iframe,當(dāng)表單被提交后,服務(wù)器返回的數(shù)據(jù)會(huì)自動(dòng)返回給iframe,這樣在表單提交后就可以不用刷新本頁面而實(shí)現(xiàn)內(nèi)容的填充
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 1.表單元素 編寫表單的三個(gè)步驟:構(gòu)建表單,服務(wù)器端處理,配置表單 以披薩預(yù)定表單為例 構(gòu)建完表單,需要服務(wù)器端提...
    hyt222閱讀 625評(píng)論 0 0
  • 1.文檔樹 Document Object Model 文檔對(duì)象模型 包含: DOM Core DOM HTM...
    hyt222閱讀 372評(píng)論 0 0
  • 福貴娘還在世的那些日子,常對(duì)福貴說:人只要活得高興,窮也不怕?!痘钪?第一次看余華的文學(xué)作品,不得不說,余華...
    走路帶風(fēng)少女閱讀 249評(píng)論 4 13
  • 成田/羽田機(jī)場 - 東京市區(qū) 此圖為JR山手線,山手線包含了東京市內(nèi)的大部分主要商圈景點(diǎn)以及交通樞紐,如新宿、銀座...
    surmoon閱讀 1,692評(píng)論 0 0

友情鏈接更多精彩內(nèi)容