表单
表单基础
Web表单在HTML中以 元素表示,在javascript中则是以 HTMLFormElement 类型表示,拥有与其他HTML元素一样的默认属性,不过也有属于自己的属性和方法:
- acceptCharset:服务器可以接受的字符集,等价于HTML的accept-charset属性
- action:请求URL
- elements:表单中所有控件的HTMLCollection(一个集合)
- length:表单中控件的数量
- method:HTTP请求方法类型,通常为 “get” 或 “post”
- name:表单的名字
- reset():把表单字段重置为默认值
- submit():提交表单
- target:用于获得发送请求和接受响应的窗口的名字
最常用的获取整个表单是把它当作普通元素为它指定一个 id 属性,使用方法 getElementById() 方法:
let form = document.getElementById("form")
注意: 表单可以同时拥有 id 和 name,而且两者可以不相同
提交表单
表单可以通过用户点击提交按钮或图片按钮的方式进行提交:
-
按钮方式:
-
使用 type 属性为 “submit” 的input
<input type="submit" value="提交表单">
-
使用 元素
<button type="submit">提交表单</button>
-
-
图片方式:
<input type="image" src="graph.gif">
以这种方式提交表单会在向服务器发送请求之前触发 submit 事件,这样就提供了一个验证表单数据的机会。可以阻止这个事件的默认行为来取消提交表单:
let form = document.getElementById("form");
form.addEventListener("submit", (event)=>{
event.preventDefault();
});
注意: 不能通过获取提交 button 的 id,来阻止提交事件,因为提交事件(包括所有的表单事件)是与表单绑定的,
提交表单的最大问题就是可能提交两次表单,解决这个问题的主要有两种方法:1. 在表单提交之后在一段的事件内禁止表单的提交按钮;2. 通过 onsubmit 事件处理程序取消之后的表单提交。
表单重置
用户单击按钮可以重置表单。按钮可以使用的方式:
-
使用 type 属性为 “reset” 的input
<input type="reset" value="重置表单">
-
使用 元素
<button type="reset">重置表单</button>
用户单击重置按钮会触发 reset 事件。这个事件为取消重置提供了机会,可以阻止这个事件的默认行为来取消提交表单:
let form = document.getElementById("form");
form.addEventListener("reset", (event)=>{
event.preventDefault();
});
表单字段
表单元素可以像页面中的其他元素一样使用原生的 DOM 方法来访问。此外,所有的表单元素都是表单 elements 属性(元素集合) 中包含的一个值。这个 elements 是一个有序集合,可以通过索引位置和 name 属性来访问:
例子:
let form = document.getElementById("form");
// 获得表单中的第一个字段
let field1 = form.elements[0];
console.log(field1);
// 获得表单中名字为 "userName" 的字段
let field2 = form.elements["userName"];
console.log(field2);
// 获取字段的数量
let length = form.length;
console.log(length);
输出结果:
如果一个表单中的控件使用了同一个 name,比如像单选框按钮那样,则会返回包含所有同名元素的HTMLCollection。
例子:
<form action="xxx" method="get" id="form">
<ul>
<li><input type="radio" name="color" value="red">Red</li>
<li><input type="radio" name="color" value="green">Green</li>
<li><input type="radio" name="color" value="blue">Blue</li>
</ul>
</form>
let form = document.getElementById("form");
let colorList = form.elements["color"];
console.log(colorList.length); // 3
colorList.forEach((value)=>{
console.log(value);
})
输出结果:
表单字段的公共属性
一下是表单字段的公共属性和方法:
- disabled::布尔值,表示表单字段是否禁用
- name:字符串,这个字段的名字
- readOnly:布尔值,这个字段是否是只读
- tabIndex:数值,表示这个字段在按下TAB键时的切换顺序
- type:字符串,表示字段类型,如 “checkBox”, “radio” 等
- value:要提交给服务器的字段值
例子:
let form = document.getElementById("form");
let field = form.elements[0];
// 修改字段的值
field.value = "Test";
// 给字段设置焦点
field.focus();
// 禁用字段
field.disabled = true;
在WEB表单中最常见的一个问题就是用户常常会点击两次提交按钮,这样就导致了表单的重复提交。对此,常见的一个解决方法就是在第一次点击提交之后就禁用掉提交按钮,可以通过监听 “submit” 事件来实现:
let form = document.getElementById("form");
form.addEventListener("submit", (event)=>{
let target = event.target;
let btn = target.elements["submit-btn"];
btn.disabled = true;
});
注意:这个功能不能通过直接给提交按钮添加 “onclick” 事件来完成,因为在不同的浏览器中,触发的时机是不一样的有些的浏览器会在触发表单的 submit 事件前先触发提交按钮的 click 事件,有些浏览器则会后触发 click 事件
表单中的公共方法
每一个表单字段都有两个公共方法:focus() 和 blur()
- focus():把浏览器焦点聚焦到表单字段上
- blur():从元素上移除焦点
在HTML5中为表单字段增加了 autofocus 属性,自动聚焦焦点:
<form action="gfgfgf" method="get" id="form">
用户名: <input type="text" placeholder="请输入用户名" name="userName" id="username" autofocus>
<br>
密码: <input type="password" placeholder="请输入密码" name="password"><br>
</form>
表单的公共事件
除了鼠标,键盘,变化和HTML事件外,所有的字段还支持一下三个事件:
- blur:失去焦点时触发
- change:在 和 元素的 value 发生变化时且失去焦点时触发,或者在 元素中选中项发生变化时触发
- focus:在字段获得焦点时触发
表单字段的自动切换
javaScript 可以通过很多方法来增强表单的易用性。最常用的就是在当前字段完成时自动切换到下一个字段。对于要收集的数据长度已知是可以这样处理的。例如:在美国,电话号码通常分为三个部分:区号,交换区号,外加4位数字,如下:
<input type="text" name="tel1" id="txtTel1" maxlength="3"><br>
<input type="text" name="tel2" id="txtTel2" maxlength="3"><br>
<input type="text" name="tel3" id="txtTel3" maxlength="4"><br>
为了增强这个表单的易用性并加速数据输入,可以在每一个文本框输入到最大允许字符数的时候自动将焦点移到下一个文本框。因此,当用户在第一个文本框输入3个字符之后,就自动把焦点移到第二个文本框,如此直到输入完成。
function tabForward(event) {
let target = event.target; // 获取input框
console.log(target);
// 如果输入的字符等于最大允许字符
if (target.value.length == target.maxLength) {
let form = target.form; // 获取整个表单
console.log(form);
// 遍历整个表单
for(let i = 0, len = form.elements.length; i < len; i++) {
// 找到当前输入完成的表单
if (form.elements[i] == target) {
// 判断下一个元素是否可用
if (form.elements[i + 1]) {
// 将表单的焦点移到下一位
form.elements[i + 1].focus();
}
return;
}
}
}
}
let input = ["txtTel1", "txtTel2", "txtTel3"];
for (let id of input) {
let textbox = document.getElementById(id);
textbox.addEventListener("keyup", tabForward);
}