牛骨文教育服务平台(让学习变的简单)

表单

Web表单是开发人员与用户交互的重要控件。

1、form

1.1 form独有的属性和方法

在HTML中,表单是由<form>来表示的,而在JavaScript中,表单对应的是HTMLFormElement类型。HTMLFormElement继承了HTMLElement,因此它跟其他HTML元素具有相同的默认属性。

<form>也有自己独有的属性和方法:

acceptCharset:服务器能够处理的字符集
action:接收请求的URL
elements:表单中所有控件的集合(HTMLCollection)
enctype:请求的编码类型
length:表单中控件的数量
method:要发送的HTTP请求类型,通常是“get”或“post”
name:表单的名称
reset():将所有表单域重置为默认值
submit():提交表单
target:用于发送请求和接收响应的窗口名称

1.2 获取表单元素

获取表单元素一般有两种方式:

  • 通过id来获取,比如获取一个id名为form1的表单元素:
    document.getElementById("form1");
    

    -通过docuemnt.forms获取name名为form1的表单元素:

    document.forms["form1]
    

    document.forms可以获取到当前页面中所有的表单元素,我们又可以通过方括号表示法获取某个属性,传入数值索引或name值。

1.3 提交表单

提交表单也有两种方式:

  • 通过<input><button>提交:
    <input type="submit" />
    

只要`<form>`内有上面这三种按钮,点击的时候就会提交表单,而且,当相应表单控件拥有焦点时,按回车键也会提交表单(焦点在textarea里例外,回车键是换行)。

- 通过JavaScript触发submit()提交:

var form1 = document.getElementById("form1");
form1.submit();

在请求发送给服务器之前,浏览器会触发submit事件,我们可以主动监听它:

var form1 = document.getElementById("form1");
form1.onsubmit = function(){

}

注意:在调用submit()方法提交表单时,不会触发submit事件。

**1.4 重置表单**

重置表单也有两种方式:
- 重置按钮

当点击重置按钮时,会触发reset事件:

form1.onreset = function(){
}


- 通过reset()方法

form1.reset();

与调用submit()不同,调用reset()方法时也会触发reset事件。

**1.5 表单字段**

除了使用原生DOM方法访问表单元素外,每一个表单都有elements属性,该属性是表单中所有元素的集合(比如`<input>、<textarea>、<button>、<fieldset>`),elements是一个有序列表,包含着表单中的所有字段。


form1.elements[0] // 取得表单中的第一个字段
form1.elements["yourname"]; // 取得name名为“yourname”的字段

如果表单内有多个同名(name)表单控件,那么用name取时,就会返回一个NodeList集合。
red

green

var colors = form1.elements["color"]

colors是一个NodeList集合,包含了上面两个radio。

**1.5.1 表单字段的共有属性**

除了`<fieldset>`元素,所有表单字段都拥有一些相同的属性。

共有的属性和方法:

disabled:布尔值,表单当前字段是否被禁用
form:指向当前字段所属表单的指针,只读
name:当前字段的名称
readonly:布尔值,表示当前字段是否只读
tabIndex:表单当前字段的切换(tab)序号
type:当前字段的类型
value:当前字段将被提交给服务器的值。

`<input>`和`<button>`元素的type属性是可以修改,但`<select>`元素则是只读的。

**1.5.2 表单字段的共有方法**

每个表单字段都有两个方法:focus()和blur()。
- focus()方法用于让表单字段获取到焦点
- blur()方法用于让表单字段失去焦点

HTML5新增了一个autofocus属性,作用相当于focus(),只要设置了此属性,表单字段就会自动获取焦点。

**1.5.3 表单字段的共有事件**

所有表单都支持下列三个事件:
- blur:当前字段失去焦点时触发
- change:对于`<input>、<textarea>`元素,在它们失去焦点且value值改变时触发,对于`<select>`元素,在选项改变时触发
- focus:当前字段获得焦点时触发

如果你要实时的监听表单字段的值是否变化,可使用如下代码:

if("oninput" in docuemnt){
input.addEventListener("input",function(){});
}else{
input.onpropertychange = function(){};
}

当支持input事件时,就使用input,否则使用onpropertychange(IE特有)

**onchange、oninput和onpropertychange三个事件的区别**:

`onchange`事件在内容改变(两次内容有可能还是相等的)且失去焦点时触发;
`oninput`事件是IE之外的大多数浏览器支持的事件,在value改变时触发,实时的,即每增加或删除一个字符就会触发,然而通过js改变value时,却不会触发;
`onpropertychange`事件是任何属性改变都会触发的,而oninput却只在value改变时触发,oninput要通过addEventListener()来注册。

**失效情况**:
- oninput事件: 当脚本中改变value时,不会触发;从浏览器的自动下拉提示中选取时,不会触发。 
- onpropertychange事件:当input设置为disabled=true后,onpropertychange不会触发。 

**2、文本框**

文本框有两种:`<input>`和`<textarea>`。


**2.1 文本框独有的属性**

`<input>`的独有属性:

size:指定文本框能够显示的字符数
maxlength:指定文本框可以接受的最大字符数


对于`<textarea>`,它还有一些独有属性:

rows:指定的文本框的字符行数
cols:指定的文本框的字符列数

注意:`<textarea>`的初始值是放在`<textarea>`和`</textarea>`之间的。

**2.2 选择文本**

文本框都支持select()方法,用于选择文本框中的所有文本。当调用select()方法时,大多数浏览器都会将焦点设置到文本框中。

当用户选择了文本框中的文本时,会触发select事件。

input.addEventListener("select",function(){});


**2.2.1 取得选择的文本**

在支持HTML5的浏览器中,我们可以获取到用户选择了什么文本,通过两个属性:selectionStart和selectionEnd,这两个属性保存的是基于0的数值,表示所选择文本的范围。
取得用户选择的文本:

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 选择部分文本**

所有文本框都有一个`setSelectionRange()`方法(支持HTML5的浏览器中),它接受两个参数:要选择的第一个字符的索引和要选择的最后一个字符的索引。

不过在IE8及之前的版本并不支持这个方法。当然,也有替代的方法。
在IE上,我们使用`createTextRange()`创建一个范围,然后使用`moveStart()`和`moveEnd()`方法将这个范围移动到需要获取文本的位置上。不过,在使用这两个方法之前,还必须使用`collpase()`将范围折叠刀文本框的开始文章,此时,`moveStart()`将范围的起点和终点都移动到了相同的位置,只要再给`moveEnd()`传入要选择的字符总数即可。最后一步,就是使用范围的`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()`两个方法其实可用看做是`setSelectionRange()`的两个分解方法,获取开始点和获取结束点。

**2.2.3 过滤输入**

对于很多文本框来说,都不会任由用户输入文本,或多或少都会有所限制,这个时候,我们就需要监听`keypress`键盘事件,通过`event`事件对象中的字符编码`keyCode`来判断输入字符是否该被屏蔽

textbox.addEventListener("keypress", function(event){
var keycode = event.keyCode;
});


**2.2.4 操作剪贴板**

剪切板事件:
- `beforecopy`:在发生复制操作前触发
- `copy`:在发生复制操作时触发
- `beforecut`:在发生剪切操作前触发
- `cut`:在发生剪切操作时触发
- `beforepaste`:在发生黏贴操作前触发
- `paste`:在发生黏贴操作时触发

要访问剪切板中的数据,可以使用`clipboardData`对象,在IE下,这个对象是`window`属性,在其他浏览器,这个对象是相应`event`对象的属性。

注意:在IE中,可以随时访问`clipboardData`对象;在其他浏览器中,只有在处理剪贴板事件期间`clipboardData`对象才有效。

`clipboardData`对象有三个方法:
- getData():用于从剪切板中取得数据,它接受一个参数,即要取得的数据的格式。在IE中,有两种数据格式:“text”和“URL”;在其他浏览器中,这个参数是一种MIME类型,比如“text/plain”,不过可以使用“text”代替“text/plain”
- setData():用于放置剪切板中的文本,它接受两个参数,第一个参数是数据格式(和getData()中的数据格式一样,IE支持“text”和“URL”,其他浏览器只支持MIME类型),第二个参数是要放在剪切板中的文本。成功的将文本放到剪切板后,都会返回true。
clearData():用于删除剪切板中指定格式的数据,它接受一个参数,即要删除数据的格式。

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 约束验证 API**

HTML5位表单字段提供了自动验证的功能,当然,要使用这些功能,开发者必须指定一些约束。

**(1)必填字段**

可以使用`required`属性来将字段定位必填字段:

只要设置了`required`属性,这个表单字段就不能为空。

当然,我们也可以使用JavaScript来获取或设置字段是否必填:

document.forms[0].elements["name"].required


由于是HTML5中定义的,我们有时需要检测浏览器是否支持:

if( "required" in document.createElement("input") ){
}


**(2)输入模式**

HTML5位文本字段新增了`pattern`属性,这个属性的值是一个正则表达式,用于匹配文本框中的值


**(3)检测有效性**

使用`checkValidity()`方法可以检测表单中的某个字段是否有效。所有表单字段都有这个方法,如果字段的值有效,则返回true,否则返回false。

if( document.forms[0].elements[0].checkValidity() ){}

当然,如果要检测整个表单是否有效,可以在表单自身调用这个方法,当所有表单字段有效,才返回true,只要有一个字段无效,则返回false。

if( document.forms[0].checkValidity() ){}


每个表单字段还有一个更有效的的属性:validity,它包含了一系列属性,每个属性会返回一个布尔值

customError:如果设置了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:如果标注为required的字段中没有值,返回true

例子:

if( input.validity && !input.validity.valid){

}


**(4)禁用验证**

通过设置`novalidate`属性,可以告诉表单不进行验证。
当然,也可以通过JavaScript设置:

document.forms[0].noValidate = true; // 禁用验证

我们也可以通过给提交按钮添加`formnovalidate`属性来禁用验证


**3、选择框**

HTML中的选择框通过`<select>`和`<option>`元素创建。
`<select>`属于HTMLSelectElement类型,有下列的独有属性和方法:
- add(newOption, relOption):向控件中插入新的`<option>`元素,其位置在相关项(relOption)之前。
- multiple:布尔值,表示是否允许多项选择
- options:控件中所有`<option>`元素的HTMLCollection。
- remove(index):移除给定位置的选项
- selectedIndex:基于0的选中项的索引,如果没有选中项,则值为-1;对于多选项来说,只保存选中项中第一项的索引
- size:选择框中可见的行数

选择框的type属性不是“select-one”,就是“select-multiple”。

选择框的value属性由当前选中项决定,相应规则如下:
- 如果没有选中的项,则选择框的value属性保存空字符串
- 如果有一个选中项,而且该项的value属性已经制定,则选择框的value等于选中项的value属性的值
- 如果有一个选中项,但该项的value属性没有指定,则选择框的value等于该项的文本
- 如果有多个选中项,则选择框的value将依据前两条规则取得第一个选中项的值。

在DOM中,每个`<option>`元素都有一个HTMLOptionElement对象,其有下列属性:
- index:当前选项在options集合中的索引
- label:当前选项的标签
- selected:布尔值,表示当前选项是否被选中。将其设置为true可以选中该项
- text:选项的文本
- value:选项的值