## 表單
Web表單是開發(fā)人員與用戶交互的重要控件。
**1、form**
**1.1 form獨(dú)有的屬性和方法**
在HTML中,表單是由`<form>`來表示的,而在JavaScript中,表單對(duì)應(yīng)的是HTMLFormElement類型。HTMLFormElement繼承了HTMLElement,因此它跟其他HTML元素具有相同的默認(rèn)屬性。
`<form>`也有自己獨(dú)有的屬性和方法:
```
acceptCharset:服務(wù)器能夠處理的字符集
action:接收請(qǐng)求的URL
elements:表單中所有控件的集合(HTMLCollection)
enctype:請(qǐng)求的編碼類型
length:表單中控件的數(shù)量
method:要發(fā)送的HTTP請(qǐng)求類型,通常是“get”或“post”
name:表單的名稱
reset():將所有表單域重置為默認(rèn)值
submit():提交表單
target:用于發(fā)送請(qǐng)求和接收響應(yīng)的窗口名稱
```
**1.2 獲取表單元素**
獲取表單元素一般有兩種方式:
- 通過id來獲取,比如獲取一個(gè)id名為form1的表單元素:
```
document.getElementById('form1');
```
-通過docuemnt.forms獲取name名為form1的表單元素:
```
document.forms['form1]
```
`document.forms`可以獲取到當(dāng)前頁面中所有的表單元素,我們又可以通過方括號(hào)表示法獲取某個(gè)屬性,傳入數(shù)值索引或`name`值。
**1.3 提交表單**
提交表單也有兩種方式:
- 通過`<input>`或`<button>`提交:
```
<input type="submit" />
<button type="submit"></button>
<input type="image" src="example.png" />
```
只要`<form>`內(nèi)有上面這三種按鈕,點(diǎn)擊的時(shí)候就會(huì)提交表單,而且,當(dāng)相應(yīng)表單控件擁有焦點(diǎn)時(shí),按回車鍵也會(huì)提交表單(焦點(diǎn)在textarea里例外,回車鍵是換行)。
- 通過JavaScript觸發(fā)submit()提交:
```
var form1 = document.getElementById('form1');
form1.submit();
```
在請(qǐng)求發(fā)送給服務(wù)器之前,瀏覽器會(huì)觸發(fā)submit事件,我們可以主動(dòng)監(jiān)聽它:
```
var form1 = document.getElementById('form1');
form1.onsubmit = function(){
}
```
注意:在調(diào)用submit()方法提交表單時(shí),不會(huì)觸發(fā)submit事件。
**1.4 重置表單**
重置表單也有兩種方式:
- 重置按鈕
```
<input type="reset" />
<button type="reset"></button>
```
當(dāng)點(diǎn)擊重置按鈕時(shí),會(huì)觸發(fā)reset事件:
```
form1.onreset = function(){
}
```
- 通過reset()方法
```
form1.reset();
```
與調(diào)用submit()不同,調(diào)用reset()方法時(shí)也會(huì)觸發(fā)reset事件。
**1.5 表單字段**
除了使用原生DOM方法訪問表單元素外,每一個(gè)表單都有elements屬性,該屬性是表單中所有元素的集合(比如`<input>、<textarea>、<button>、<fieldset>`),elements是一個(gè)有序列表,包含著表單中的所有字段。
```
<form id="form1">
<input type="text" name="yourname" />
<textarea name="intro"></textarea>
</form>
form1.elements[0] // 取得表單中的第一個(gè)字段
form1.elements['yourname']; // 取得name名為“yourname”的字段
```
如果表單內(nèi)有多個(gè)同名(name)表單控件,那么用name取時(shí),就會(huì)返回一個(gè)NodeList集合。
```
<form id="form1">
<input type="radio" name="color" /> red
<input type="radio" name="color" /> green
</form>
var colors = form1.elements['color']
```
colors是一個(gè)NodeList集合,包含了上面兩個(gè)radio。
**1.5.1 表單字段的共有屬性**
除了`<fieldset>`元素,所有表單字段都擁有一些相同的屬性。
共有的屬性和方法:
```
disabled:布爾值,表單當(dāng)前字段是否被禁用
form:指向當(dāng)前字段所屬表單的指針,只讀
name:當(dāng)前字段的名稱
readonly:布爾值,表示當(dāng)前字段是否只讀
tabIndex:表單當(dāng)前字段的切換(tab)序號(hào)
type:當(dāng)前字段的類型
value:當(dāng)前字段將被提交給服務(wù)器的值。
```
`<input>`和`<button>`元素的type屬性是可以修改,但`<select>`元素則是只讀的。
**1.5.2 表單字段的共有方法**
每個(gè)表單字段都有兩個(gè)方法:focus()和blur()。
- focus()方法用于讓表單字段獲取到焦點(diǎn)
- blur()方法用于讓表單字段失去焦點(diǎn)
HTML5新增了一個(gè)autofocus屬性,作用相當(dāng)于focus(),只要設(shè)置了此屬性,表單字段就會(huì)自動(dòng)獲取焦點(diǎn)。
**1.5.3 表單字段的共有事件**
所有表單都支持下列三個(gè)事件:
- blur:當(dāng)前字段失去焦點(diǎn)時(shí)觸發(fā)
- change:對(duì)于`<input>、<textarea>`元素,在它們失去焦點(diǎn)且value值改變時(shí)觸發(fā),對(duì)于`<select>`元素,在選項(xiàng)改變時(shí)觸發(fā)
- focus:當(dāng)前字段獲得焦點(diǎn)時(shí)觸發(fā)
如果你要實(shí)時(shí)的監(jiān)聽表單字段的值是否變化,可使用如下代碼:
```
if('oninput' in docuemnt){
input.addEventListener('input',function(){});
}else{
input.onpropertychange = function(){};
}
```
當(dāng)支持input事件時(shí),就使用input,否則使用onpropertychange(IE特有)
**onchange、oninput和onpropertychange三個(gè)事件的區(qū)別**:
`onchange`事件在內(nèi)容改變(兩次內(nèi)容有可能還是相等的)且失去焦點(diǎn)時(shí)觸發(fā);
`oninput`事件是IE之外的大多數(shù)瀏覽器支持的事件,在value改變時(shí)觸發(fā),實(shí)時(shí)的,即每增加或刪除一個(gè)字符就會(huì)觸發(fā),然而通過js改變value時(shí),卻不會(huì)觸發(fā);
`onpropertychange`事件是任何屬性改變都會(huì)觸發(fā)的,而oninput卻只在value改變時(shí)觸發(fā),oninput要通過addEventListener()來注冊。
**失效情況**:
- oninput事件: 當(dāng)腳本中改變value時(shí),不會(huì)觸發(fā);從瀏覽器的自動(dòng)下拉提示中選取時(shí),不會(huì)觸發(fā)。
- onpropertychange事件:當(dāng)input設(shè)置為disabled=true后,onpropertychange不會(huì)觸發(fā)。
**2、文本框**
文本框有兩種:`<input>`和`<textarea>`。
```
<input type="text" />
<textarea cols ="10" rows ="5"></textarea>
```
**2.1 文本框獨(dú)有的屬性**
`<input>`的獨(dú)有屬性:
```
size:指定文本框能夠顯示的字符數(shù)
maxlength:指定文本框可以接受的最大字符數(shù)
```
對(duì)于`<textarea>`,它還有一些獨(dú)有屬性:
```
rows:指定的文本框的字符行數(shù)
cols:指定的文本框的字符列數(shù)
```
注意:`<textarea>`的初始值是放在`<textarea>`和`</textarea>`之間的。
**2.2 選擇文本**
文本框都支持select()方法,用于選擇文本框中的所有文本。當(dāng)調(diào)用select()方法時(shí),大多數(shù)瀏覽器都會(huì)將焦點(diǎn)設(shè)置到文本框中。
當(dāng)用戶選擇了文本框中的文本時(shí),會(huì)觸發(fā)select事件。
```
input.addEventListener('select',function(){});
```
**2.2.1 取得選擇的文本**
在支持HTML5的瀏覽器中,我們可以獲取到用戶選擇了什么文本,通過兩個(gè)屬性:selectionStart和selectionEnd,這兩個(gè)屬性保存的是基于0的數(shù)值,表示所選擇文本的范圍。
取得用戶選擇的文本:
```
function getSelectedText(textbox){
if(typeof textbox.selectionStart == 'number'){
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
}else if(document.selection){
return document.selection.createRange().text;
}
}
```
IE8之前不支持selectionStart。
**2.2.2 選擇部分文本**
所有文本框都有一個(gè)`setSelectionRange()`方法(支持HTML5的瀏覽器中),它接受兩個(gè)參數(shù):要選擇的第一個(gè)字符的索引和要選擇的最后一個(gè)字符的索引。
不過在IE8及之前的版本并不支持這個(gè)方法。當(dāng)然,也有替代的方法。
在IE上,我們使用`createTextRange()`創(chuàng)建一個(gè)范圍,然后使用`moveStart()`和`moveEnd()`方法將這個(gè)范圍移動(dòng)到需要獲取文本的位置上。不過,在使用這兩個(gè)方法之前,還必須使用`collpase()`將范圍折疊刀文本框的開始文章,此時(shí),`moveStart()`將范圍的起點(diǎn)和終點(diǎn)都移動(dòng)到了相同的位置,只要再給`moveEnd()`傳入要選擇的字符總數(shù)即可。最后一步,就是使用范圍的`select()`方法選擇文本。
```
function selectText(textbox, startIndex, stopIndex){
if(textbox.setSelectionRange){
textbox.setSelectionRange(startIndex, stopIndex);
}else if(textbox.createTextRange()){
var range = document.createTextRange();
range.collapse(true);
range.moveStart('character', startIndex);
range.moveEnd('character', stopIndex - startIndex);
range.select();
}
textbox.focus();
}
```
`moveStart()`和`moveEnd()`兩個(gè)方法其實(shí)可用看做是`setSelectionRange()`的兩個(gè)分解方法,獲取開始點(diǎn)和獲取結(jié)束點(diǎn)。
**2.2.3 過濾輸入**
對(duì)于很多文本框來說,都不會(huì)任由用戶輸入文本,或多或少都會(huì)有所限制,這個(gè)時(shí)候,我們就需要監(jiān)聽`keypress`鍵盤事件,通過`event`事件對(duì)象中的字符編碼`keyCode`來判斷輸入字符是否該被屏蔽
```
textbox.addEventListener('keypress', function(event){
var keycode = event.keyCode;
});
```
**2.2.4 操作剪貼板**
剪切板事件:
- `beforecopy`:在發(fā)生復(fù)制操作前觸發(fā)
- `copy`:在發(fā)生復(fù)制操作時(shí)觸發(fā)
- `beforecut`:在發(fā)生剪切操作前觸發(fā)
- `cut`:在發(fā)生剪切操作時(shí)觸發(fā)
- `beforepaste`:在發(fā)生黏貼操作前觸發(fā)
- `paste`:在發(fā)生黏貼操作時(shí)觸發(fā)
要訪問剪切板中的數(shù)據(jù),可以使用`clipboardData`對(duì)象,在IE下,這個(gè)對(duì)象是`window`屬性,在其他瀏覽器,這個(gè)對(duì)象是相應(yīng)`event`對(duì)象的屬性。
注意:在IE中,可以隨時(shí)訪問`clipboardData`對(duì)象;在其他瀏覽器中,只有在處理剪貼板事件期間`clipboardData`對(duì)象才有效。
`clipboardData`對(duì)象有三個(gè)方法:
- getData():用于從剪切板中取得數(shù)據(jù),它接受一個(gè)參數(shù),即要取得的數(shù)據(jù)的格式。在IE中,有兩種數(shù)據(jù)格式:“text”和“URL”;在其他瀏覽器中,這個(gè)參數(shù)是一種MIME類型,比如“text/plain”,不過可以使用“text”代替“text/plain”
- setData():用于放置剪切板中的文本,它接受兩個(gè)參數(shù),第一個(gè)參數(shù)是數(shù)據(jù)格式(和getData()中的數(shù)據(jù)格式一樣,IE支持“text”和“URL”,其他瀏覽器只支持MIME類型),第二個(gè)參數(shù)是要放在剪切板中的文本。成功的將文本放到剪切板后,都會(huì)返回true。
clearData():用于刪除剪切板中指定格式的數(shù)據(jù),它接受一個(gè)參數(shù),即要?jiǎng)h除數(shù)據(jù)的格式。
```
function getClipboardText(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData('text');
}
function setClipboardText(event, value){
if(event.clipboardData){
return event.clipboardData.setData('text/plain', value);
}else if(window.clipboardData){
return window.clipboardData.setData('text', value);
}
}
```
**2.2.5 HTML5 約束驗(yàn)證 API**
HTML5位表單字段提供了自動(dòng)驗(yàn)證的功能,當(dāng)然,要使用這些功能,開發(fā)者必須指定一些約束。
**(1)必填字段**
可以使用`required`屬性來將字段定位必填字段:
```
<input type="text" required />
```
只要設(shè)置了`required`屬性,這個(gè)表單字段就不能為空。
當(dāng)然,我們也可以使用JavaScript來獲取或設(shè)置字段是否必填:
```
document.forms[0].elements['name'].required
```
由于是HTML5中定義的,我們有時(shí)需要檢測瀏覽器是否支持:
```
if( 'required' in document.createElement('input') ){
}
```
**(2)輸入模式**
HTML5位文本字段新增了`pattern`屬性,這個(gè)屬性的值是一個(gè)正則表達(dá)式,用于匹配文本框中的值
```
<input type="text" pattern="\d+" />
```
**(3)檢測有效性**
使用`checkValidity()`方法可以檢測表單中的某個(gè)字段是否有效。所有表單字段都有這個(gè)方法,如果字段的值有效,則返回true,否則返回false。
```
if( document.forms[0].elements[0].checkValidity() ){}
```
當(dāng)然,如果要檢測整個(gè)表單是否有效,可以在表單自身調(diào)用這個(gè)方法,當(dāng)所有表單字段有效,才返回true,只要有一個(gè)字段無效,則返回false。
```
if( document.forms[0].checkValidity() ){}
```
每個(gè)表單字段還有一個(gè)更有效的的屬性:validity,它包含了一系列屬性,每個(gè)屬性會(huì)返回一個(gè)布爾值
```
customError:如果設(shè)置了setCustomValidity(),則為true,否則為false。
patternMismatch:如果值與指定的pattern屬性不匹配,返回true
rangeOverflow:如果值比max值大,返回true
rangeUnderflow:如果值比min值小,返回true
stepMisMatch:如果min和max之間的步長值不合理,返回true
tooLong:如果值的長度超過了maxlength屬性指定的長度,返回true
typeMismatch:如果值不是“mail”或“url”要求的格式,返回true
valid:如果這里的其他屬性都是false,返回true
valueMissing:如果標(biāo)注為required的字段中沒有值,返回true
```
例子:
```
if( input.validity && !input.validity.valid){
}
```
**(4)禁用驗(yàn)證**
通過設(shè)置`novalidate`屬性,可以告訴表單不進(jìn)行驗(yàn)證。
```
<form novalidate></form>
```
當(dāng)然,也可以通過JavaScript設(shè)置:
```
document.forms[0].noValidate = true; // 禁用驗(yàn)證
```
我們也可以通過給提交按鈕添加`formnovalidate`屬性來禁用驗(yàn)證
```
<form>
<input type="submit" formnovalidate />
</form>
```
**3、選擇框**
HTML中的選擇框通過`<select>`和`<option>`元素創(chuàng)建。
`<select>`屬于HTMLSelectElement類型,有下列的獨(dú)有屬性和方法:
- add(newOption, relOption):向控件中插入新的`<option>`元素,其位置在相關(guān)項(xiàng)(relOption)之前。
- multiple:布爾值,表示是否允許多項(xiàng)選擇
- options:控件中所有`<option>`元素的HTMLCollection。
- remove(index):移除給定位置的選項(xiàng)
- selectedIndex:基于0的選中項(xiàng)的索引,如果沒有選中項(xiàng),則值為-1;對(duì)于多選項(xiàng)來說,只保存選中項(xiàng)中第一項(xiàng)的索引
- size:選擇框中可見的行數(shù)
選擇框的type屬性不是“select-one”,就是“select-multiple”。
選擇框的value屬性由當(dāng)前選中項(xiàng)決定,相應(yīng)規(guī)則如下:
- 如果沒有選中的項(xiàng),則選擇框的value屬性保存空字符串
- 如果有一個(gè)選中項(xiàng),而且該項(xiàng)的value屬性已經(jīng)制定,則選擇框的value等于選中項(xiàng)的value屬性的值
- 如果有一個(gè)選中項(xiàng),但該項(xiàng)的value屬性沒有指定,則選擇框的value等于該項(xiàng)的文本
- 如果有多個(gè)選中項(xiàng),則選擇框的value將依據(jù)前兩條規(guī)則取得第一個(gè)選中項(xiàng)的值。
在DOM中,每個(gè)`<option>`元素都有一個(gè)HTMLOptionElement對(duì)象,其有下列屬性:
- index:當(dāng)前選項(xiàng)在options集合中的索引
- label:當(dāng)前選項(xiàng)的標(biāo)簽
- selected:布爾值,表示當(dāng)前選項(xiàng)是否被選中。將其設(shè)置為true可以選中該項(xiàng)
- text:選項(xiàng)的文本
- value:選項(xiàng)的值
- 前言
- JavaScript簡介
- 基本概念
- 語法
- 數(shù)據(jù)類型
- 運(yùn)算符
- 表達(dá)式
- 語句
- 對(duì)象
- 數(shù)組
- 函數(shù)
- 引用類型(對(duì)象)
- Object對(duì)象
- Array對(duì)象
- Date對(duì)象
- RegExp對(duì)象
- 基本包裝類型(Boolean、Number、String)
- 單體內(nèi)置對(duì)象(Global、Math)
- console對(duì)象
- DOM
- DOM-屬性和CSS
- BOM
- Event 事件
- 正則表達(dá)式
- JSON
- AJAX
- 表單和富文本編輯器
- 表單
- 富文本編輯器
- canvas
- 離線應(yīng)用
- 客戶端存儲(chǔ)(Cookie、Storage、IndexedDB)
- HTML5 API
- Video/Audio
- Geolocation API
- requestAnimationFrame
- File API
- FullScreen API
- IndexedDB
- 檢測設(shè)備方向
- Blob
- vibrate
- Luminosity API
- WebRTC
- Page Visibility API
- Performance API
- Web Speech
- Notification
- 面向?qū)ο蟮某绦蛟O(shè)計(jì)
- 概述
- this關(guān)鍵字
- 原型鏈
- 作用域
- 常用API合集
- SVG
- 錯(cuò)誤處理機(jī)制
- JavaScript開發(fā)技巧合集
- 編程風(fēng)格
- 垃圾回收機(jī)制
