1.基础知识
表单对应的是HTMLFormElement类型,继承自HTMLElement。
属性和方法如下:
- acceptCharset:服务器能够处理的字符集;等价于HTML中的accept-charset特性。
- action:接受请求的URL;等价于HTML中的action特性。
- elements:表单中所有控件的集合。
- enctype:请求的编码类型;等价于HTML中的enctype特性。
- length:表单中的控件数量。
- method:要发送的HTTP请求类型,通常是‘get’和‘post’;等价于HTML的method特性。
- name:表单的名称;等价于HTML的name特性。
- reset():将所有表单域重置位默认值。
- submit(): 提交表单
- target:用于发送请求和接收响应的窗口名称;等价于HTML的target特性。
获取form,可以通过getElementById获取,也可以通过数值索引和name值获取。document.forms[0]
或者document.forms['forms0']
;
1.1提交表单
<!--通用提交按钮-->
<input type="submit" value="submit form">
<!--自定义提交按钮-->
<button type="submit">submit form</button>
<!--图像按钮-->
<input type="image" src="test.jpg">
只要表单中存在上面列出的任何一种按钮,那么在相应表单控件拥有焦点的情况下,按回车键就可以提交表单。(textarea是一个例外,在文本区回车换行。)如果表单里没有提交按钮,按回车键不会提交表单。
使用preventDefault()事件,可以阻止提交事件。
var myForm = document.getElementById('myForm');
myForm.onsubmit = function (ev) {
ev.preventDefault(); // 取消表单提交
}
使用submit()可以直接提交表单。
var myForm = document.getElementById('myForm');
myForm.submit();
在调用submit()方法的形式提交表单时,不会触发submit()事件,因此要记得在调用此方法之前先验证表单数据。
1.2 重置表单
<!--自定义重置按钮-->
<button type="reset">恢复</button>
<!--通用重置按钮-->
<input type="reset" value="reset">
通过event.preventDefault()
可以阻止重置表单
通过获取表单的节点,重置表单。
<button type="button" onclick="resetForm()">恢复</button>
function resetForm() {
var myForm = document.getElementById('myForm');
myForm.reset();
}
1.3表单字段
每个表单都有elements属性,该属性是表单中所有表单元素(字段)的集合。这个elements集合是一个有序元素,包含表单所有字段。每个表单字段在elements集合中的顺序,与它们出现标记中的顺序相同,可以按照位置和name特性来访问它们。
var form = document.getElementById('form1');
// 取得表单中的第一个字段
var field1 = form.elements[0];
// 取得名为“textbox1”的字段
var field2 = form.elements['textbox1];
// 取得表单中包含的字段的数量
var fieldCount = form.elemenets.length;
如果有多个表单控件都在使用同一个name,那么返回以该name命名的NodeList。
<form id="form2">
<ul>
<li><input type="radio" name="color" value="red" checked>red</li>
<li><input type="radio" name="color" value="blue">blue</li>
<li><input type="radio" name="color" value="pink">pink</li>
</ul>
</form>
<script>
function myForm2() {
let form2 = document.getElementById('form2');
let colorFields = form2.elements['color'];
console.log(colorFields) // RadioNodeList(3) [input, input, input, value: "red"]
console.log(colorFields.value) // 获取选中值
}
</script>
1.表单共有的属性
除了<fieldset>
外,所有表单字段都包括disabled,form,name,readOnly,tabIndex,type,value
除了form属性外,可以通过js动态修改其他任何属性。
除了<fieldset>
外,所有表单字段都有type属性。
2.共有的表单字段方法
每个表单字段都有两个方法:focus()和blur()。其中,focus()方法用于将浏览器的焦点设置到表单字段,即激活表单字段,使其可以响应键盘事件。
HTML5为表单字段新增了一个autofocus的属性,在支持此属性的浏览器中,只要设置这个属性,可以将焦点移动到相应字段。
<input type="text" autofocus>
使用element.autofocus可以判断浏览器是否支持该属性,因为在支持的浏览器中该值为true,而不支持的浏览器中该值为空字符串。支持此属性的浏览器有Firefox4+,Safari5+,Chrome,Opera9.6.
注意在默认情况下,只有表单字段可以获取焦点。其他元素,如果先将其tabIndex置为-1,然后再调用focus()方法,也可以让这些元素获得焦点。
blur()的作用是移除焦点。
3.共有表单字段事件
blur,focus不介绍了
change:对于<input>
和<textarea>
元素,在它们失去焦点且value值改变时触发;对于<select>
元素,在其选项改变时触发。
<ul id="ul0">
<li><input type="radio" name="color" value="red">red</li>
<li><input type="radio" name="color" value="blue">blue</li>
<li><input type="radio" name="color" value="pink">pink</li>
</ul>
// 事件委托
var ul0 = document.getElementById('ul0');
ul0.addEventListener('change', function (event) {
console.log(event.target.value) // 获取radio的值
})
获取复选框的值
<ul id="ul1">
<li><input type="checkbox" name="color" value="red">red</li>
<li><input type="checkbox" name="color" value="blue">blue</li>
<li><input type="checkbox" name="color" value="pink">pink</li>
</ul>
var checkValues = [];
var ul1 = document.getElementById('ul1');
ul1.addEventListener('change', function (event) {
if (event.target.checked && checkValues.indexOf(event.target.value) === -1 ) {
console.log(event.target.value);
checkValues.push(event.target.value);
} else {
var index = checkValues.indexOf(event.target.value);
checkValues.splice(index)
}
});
2.文本框脚本
两种文本框:1.使用<input>
的单行文本框2.使用<textarea>
的多行文本框。
2.1选择文本
以上两种文本框都支持select()方法,这个方法用于选择文本框中的所有文本。在调用select()方法时,大多数浏览器都会将焦点设置到文本框中。这个方法不接受参数,可以在任何时候调用。
2.1.1选择事件
select事件支持所有的浏览器,只是触发select事件的方式不同。在IE9+、Opera、Firefox、Chrome和Safari浏览器中,只要用户选择了文本就会触发该事件,而在IE8及更早版本中,只要用户选择了一个字母(不必释放鼠标),就会触发select事件。另外在调用select()方法时,也会触发select事件。
2.1.2取得选择的文本
该规范是添加两个属性:selectionStart和selectionEnd。这两个属性中保存的都是基于0的数值,表示所选择的文本范围(即文本选区开头和结尾的偏移量)。要取得用户在文本框中选择的文本,可以采用如下代码:
<textarea placeholder="请输入文字" id="textarea0"></textarea>
var textarea = document.getElementById('textarea0');
textarea.addEventListener('select', function (event) {
console.log(textarea.value, textarea.selectionStart, textarea.selectionEnd); console.log(textarea.value.substring(textarea.selectionStart, textarea.selectionEnd)) // 获取选中的文本
})
IE8不支持这两个属性。为了使IE8也实现此效果,可以使用document.selection
对象。
if (document.selection){
return document.selection.createRange().text;
}
2.1.3选择部分文本
HTML5为选择文本框中的部分文本提供了解决方案,现在所有的文本框都有一个setSelectionRange()方法。这个方法支持两个参数:要选择的第一个字符的索引和要选择的最后一个字符的索引。此方法不是获取选中部分的值,而是控制光标的位置。
var textarea = document.getElementById('textarea0');
textarea.addEventListener('select', function (event) {
const text0 = textarea.value;
console.log(text0, text0.length);
textarea.setSelectionRange(0, 10)
})
IE8及之前的浏览器,需要使用createTextRange()方法创建范围。
跨浏览器兼容的代码如下:
function selectText(textbox, startIndex, stopIndex){
if (textbox.setSelectionRange) {
textbox.setSelectionRange(startIndex, stopIndex);
} else if(textbox.createTextRange) {
var range = textbox.createTextRange();
range.collapse(true);
range.moveStart("character", startIndex);
range.moveEnd("character", stopIndex - startIndex);
range.select();
}
textbox.focus();
}
// 使用
// 选择所有文本
selectText(textbox, 0, textbox.value.length)
2.2过滤输入
需求:希望用户输入的文本中包含或者不包含特定的字符。
用户在输入时会调用keypress事件。因此可以阻止这个事件的默认行为来屏蔽不希望出现的字符。
如果只希望屏蔽部分字符,可以参考下方代码:
if (!/\d/.test(String.fromCharCode(charCode)) && charCode > 9 && !event.ctrlKey){
event.preventDefault();
}
2.3操作剪贴板
6个剪贴板事件:
beforecopy:在发生复制操作前触发
copy:在发生复制操作时触发
beforecut:在发生剪切操作前触发
cut:在发生剪切操作时触发
beforepaste:在发生粘贴操作前触发
paste:在发生粘贴操作时触发
在实际的事件发生之前,通过beforecopy,beforecut和beforepaste事件可以在向剪贴板发送数据,或者从剪贴板取得数据之前修改数据。
访问剪贴板的数据,可以使用cliboardData对象,在IE中这个对象是window对象的属性;而在Firefox 4+,Safari和Chrome中是event的属性。
这个clipboardData对象有三个方法:getData(),setData()和clearData().
getData():从剪贴板中取得数据,它接受一个参数,即要取得的数据的格式。在IE中,有两种数据格式:“text”和“URL”。在Firefox,Safari,Chrome中,这三个参数是一种MIME类似;可以使用text代替‘text/plain’
setData():第一个参数数据类型,第二个参数是放在剪贴板中的文本。对于第一个参数,IE支持text和URL,而Safari和Chrome只支持MIME类型。但是Safari和Chrome不能识别text类型。两个浏览器在成功将文本放到剪贴板中后,都会返回true;否则,返回false。
// 获取剪贴板数据
var getData = function (event) {
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData('text');
}
// 设置数据
var setData = function (event, value) {
if (event.clipboardData) {
return event.clipboardData.setData("text/plain", value);
} else if (window.clipboardData){
return window.clipboardData.setData("text", value);
}
}
前面讲到在剪贴时,可以修改数据,下面提供一个示例:
function copyText(){
var textbox = document.getElementById('text1');
textbox.addEventListener('copy', function (event) {
console.log(event.target.value);
event.clipboardData.setData("text/plain", "你好" + event.target.value);
console.log(event.clipboardData.getData('text'))
})
}
2.4HTML5约束字段API
1.必填字段
required属性
2.其他输入类型
html5新增了几个类型,如email,url等
3.数值范围
新增了几个数值类型,如number,datetime,date,month,week,range,time。但是部分浏览器可能不兼容。
4.输入模式
h5为文本字段新增了pattern属性。这个属性是一个正则表达式,用来匹配文本框中的值。
<input type="text" pattern="\d+" name="count">
注意,模式的开头和结尾不需要加^
和$
5.检测有效性
使用checkValidity()方法可以检测表单中某个字段是否有效。所有表单字段都有这个方法,如果有效返回true否则返回false。
如果要检测整个表单是否有效,可以在表单自身调用checkValidity()方法。如果所有表单字段都有效,这个方法返回true,即使一个字段无效,也会返回false。
validity属性可以告诉你为什么字段有效或者无效。这个对象包含一系列属性。如下图
6.禁用验证
设置novalidate属性,可以让表单不进行验证
<form method="post" novalidate>
</form>
在js中使用noValidate属性可以取得或者设置这个值,若值存在为true,否则false。
3.选择框脚本
select选择框,是HTMLSelectElement类型:
- add(newOption, relOption):向控件中插入新
<option>
元素,其位置在相关项(relOption)之前。 - multiple:布尔值,表示是否允许多项选择;等价于HTML中的multiple特性。
- options:控件中所有
<option>
元素的HTMLCollection. - remove(index): 移除给定位置的选项
- selectedIndex:基于0的选中项,如果没有选中项,则值为-1。对于支持多选的控件,只保存选中项中的第一项的索引。
- size:选择框中可见的行数;等价于HTML中的size特性。size是设置在
<select>
中,表示options的可见数目
选择框的type属性取决于multiple,如果没有此属性,那么type就是select-one,否则就是select-multiple。
- 如果没有选中项,则value为空字符串
- 有一个选中项,则value等于选中项的值
- 如果有一项选中,但该项value特性未指定,则选择框的value属性等于该项文本(
<option>aaa</option>
) - 如果有多个选中项,则选择框value属性将依据前2条规则取得第一个选中项的值。
options的属性如下:
index:当前选项在options集合中的索引
label:当前选项的标签;等价于HTML中的label特性
selected:布尔值,表示当前选项是否被选中。将这个属性设置为true可以选中当前选项。
text:选项的文本
value:选项的值(option中的value值)
示例:
<select name="hobby" id="hobby">
<option value="篮球">篮球</option>
<option value="乒乓球">乒乓球</option>
<option value="网球">网球</option>
</select>
<script>
var hobby = document.getElementById('hobby');
console.log(hobby.options) // HTMLOptionsCollection(3) [option, option, option, selectedIndex: 0]
hobby.options[0].value // 篮球
hobby.options[0].text // 篮球
hobby.options[0].selected // true
// 向末尾添加option
var newoption = document.createElement('option');
newoption.text = '羽毛球'
newoption.value = '羽毛球'
hobby.add(newoption, null)
// 向篮球后面加入option
var newoption2 = document.createElement('option');
newoption2.text = '桌球'
newoption2.value = '桌球'
var rel = hobby.options[1]
hobby.add(newoption2, rel)
</script>
4.表单序列化
利用表单字段的type属性,连同name和value属性一起实现对表单的序列化。推荐使用jQuery的表单序列化,比原生简单很多。
jq:
$("button").click(function(){
$("div").text($("form").serialize());
});
原生:
Object.prototype.serialize = function(){
var res = [], //存放结果的数组
current = null, //当前循环内的表单控件
i, //表单NodeList的索引
len, //表单NodeList的长度
k, //select遍历索引
optionLen, //select遍历索引
option, //select循环体内option
optionValue, //select的value
form = this; //用form变量拿到当前的表单,易于辨识
for(i=0, len=form.elements.length; i<len; i++){
current = form.elements[i];
//disabled表示字段禁用,需要区分与readonly的区别
if(current.disabled) continue;
switch(current.type){
//可忽略控件处理
case "file": //文件输入类型
case "submit": //提交按钮
case "button": //一般按钮
case "image": //图像形式的提交按钮
case "reset": //重置按钮
case undefined: //未定义
break;
//select控件
case "select-one":
case "select-multiple":
if(current.name && current.name.length){
console.log(current)
for(k=0, optionLen=current.options.length; k<optionLen; k++){
option = current.options[k];
optionValue = "";
if(option.selected){
if(option.hasAttribute){
optionValue = option.hasAttribute('value') ? option.value : option.text
}else{
//低版本IE需要使用特性 的specified属性,检测是否已规定某个属性
optionValue = option.attributes('value').specified ? option.value : option.text;
}
res.push(encodeURIComponent(current.name) + "=" + encodeURIComponent(optionValue));
}
}
}
break;
//单选,复选框
case "radio":
case "checkbox":
//这里有个取巧 的写法,这里的判断是跟下面的default相互对应。
//如果放在其他地方,则需要额外的判断取值
if(!current.checked) break;
default:
//一般表单控件处理
if(current.name && current.name.length){
res.push(encodeURIComponent(current.name) + "=" + encodeURIComponent(current.value));
}
}
}
return res.join("&");
}
评论列表
已有0条评论