14.1 表单的基础知识
HTML 中,表单是由<form>元素来表示的,而在 JavaScript 中,表单对应的则是 HTMLFormElement 类型。HTMLFormElement 也有它自己下列独有的属性和方法。
- acceptCharset:服务器能够处理的字符集;等价于 HTML 中的 accept-charset 特性。
- action:接受请求的 URL;等价于 HTML 中的 action 特性。
- elements:表单中所有控件的集合(HTMLCollection)。
- enctype:请求的编码类型;等价于 HTML 中的 enctype 特性。
- length:表单中控件的数量。
- method:要发送的 HTTP 请求类型,通常是"get"或"post";等价于 HTML 的 method 特性。
- name:表单的名称;等价于 HTML 的 name 特性。
- reset():将所有表单域重置为默认值。
- submit():提交表单。
- target:用于发送请求和接收响应的窗口名称;等价于 HTML 的 target 特性。
获取<form>元素
// getElementById()
var form = document.getElementById("form1");
// document.forms 可以取得页面中所有的表单
var firstForm = document.forms[0]; //取得页面中的第一个表单
var myForm = document.forms["form2"]; //取得页面中名称为"form2
14.1.1 提交表单
用户单击提交按钮或图像按钮时,就会提交表单。
<!-- 通用提交按钮 -->
<input type="submit" value="Submit Form">
<!-- 自定义提交按钮 -->
<button type="submit">Submit Form</button>
<!-- 图像按钮 -->
<input type="image" src="graphic.gif">
以上3种按钮方式提交表单时,浏览器会在将请求发送给服务器之前触发 submit 事件,进而校验表单。
以编程方式调用 submit()方法也可以提交表单
var form = document.getElementById("myForm");
//提交表单
form.submit();
在调用 submit()方法的形式提交表单时,不会触发 submit 事件,因此要记得在调用此方法之前先验证表单数据。
14.1.2 重置表单
在用户单击重置按钮时,表单会被重置。
<!-- 通用重置按钮 -->
<input type="reset" value="Reset Form">
<!-- 自定义重置按钮 -->
<button type="reset">Reset Form</button>
以编程方式调用 用 reset()方法也可以提交表单
var form = document.getElementById("myForm");
//重置表单
form.reset();
调用 reset()方法会像单击重置按钮一样触发 reset 事件
14.1.3 表单字段
可以像访问页面中的其他元素一样,使用原生 DOM 方法访问表单元素。此外,每个表单都有elements 属性,该属性是表单中所有表单元素(字段)的集合,是个有序列表。
共有的表单字段属性
- disabled:布尔值,表示当前字段是否被禁用。
- form:指向当前字段所属表单的指针;只读。
- name:当前字段的名称。
- readOnly:布尔值,表示当前字段是否只读。
- tabIndex:表示当前字段的切换(tab)序号。
- type:当前字段的类型,如"checkbox"、"radio",等等。
- value:当前字段将被提交给服务器的值。
共有的表单字段方法
- focus()
- blur()
共有的表单字段事件
- blur:当前字段失去焦点时触发。
- change:对于<input>和<textarea>元素,在它们失去焦点且 value 值改变时触发;对于 <select>元素,在其选项改变时触发。
- focus:当前字段获得焦点时触发。
14.2 文本框脚本
一种是使用<input>元素的单行文本框,另一种是使用<textarea>的多行文本框。
input 元素常用属性及用法
- 必须将<input>元素的 type 特性设置为"text"。
- 设置 size 特性,可以指定文本框中能够显示的字符数
- 通过 value 特性,可以设置文本框的初始值
- maxlength 特性则用于指定文本框可以接受的最大字符数
<input type="text" size="25" maxlength="50" value="initial value">
textarea 元素常用属性及用法
- rows 特性指定的是文本框的字符行数
- cols 特性指定的是文本框的字符列数
- <textarea>的初始值必须要放在<textarea>和</textarea>之间
- 不能在 HTML 中给<textarea>指定最大字符数。
14.2.1 选择文本
select()方法用于选择文本框中的所有文本。这个方法不接受参数,可以在任何时候被调用。
var textbox = document.forms[0].elements["textbox1"];
textbox.select();
select()方法对应的,是一个 select 事件。通过select 事件我们知道用户什么时候选的,但是不知道选了什么。HTML5添加两个属性:selectionStart 和 selectionEnd,已选择的文本选区开头和结尾的偏移量。
14.2.2 过滤输入
响应向文本框中插入字符操作的是 keypress 事件。因此,可以通过阻止这个事件的默认行为来屏蔽此类字符。
textbox.addEventListener("keypress", function(event){
event = event || window.event
event.preventDefault()
});
HTML 5 后来也把剪贴板事件纳入了规范。下列就是 6 个剪贴板事件
- beforecopy:在发生复制操作前触发。
- copy:在发生复制操作时触发。
- beforecut:在发生剪切操作前触发。
- cut:在发生剪切操作时触发。
- beforepaste:在发生粘贴操作前触发。
- paste:在发生粘贴操作时触发。
要访问剪贴板中的数据,可以使用 clipboardData 对象
- IE 中,这个对象是 window 对象的属性;
- 标准浏览器这个对象是相应 event 对象的属性
这个 clipboardData 对象有三个方法:getData()、setData()和 clearData()
14.2.3 自动切换焦点
使用 JavaScript 可以从多个方面增强表单字段的易用性。其中,最常见的一种方式就是在用户填写 完当前字段时,自动将焦点切换到下一个字段。在前一个文本框中的字符达到最大数量后,自动将焦点切 换到下一个文本框。
14.2.4 HTML5 约束验证API
HTML5 新增了一些功能,即便 JavaScript被禁用或者由于种种原因未能加载,也可以确保基本的验证。换句话说,浏览器自己会根据标记中的规则执行验证,然后自己显示适当的错误消息(完全不用 JavaScript 插手)。
required 属性,任何标注有 required 的字段,在提交表单时都不能空着。
<input type="text" name="username" required>
HTML5 为<input>元素的 type 属性又增加了几个值。这些新的类型不仅能反映数据类型的信息, 而且还能提供一些默认的验证功能。
<input type="email" name ="email">
<input type="url" name="homepage">
除了 type="email" 和 type="url",还有"number"、"range"、"datetime"、"datetime-local"、"date"、"month"、"week",还有"time"。
HTML5 为文本字段新增了 pattern 属性。这个属性的值是一个正则表达式,用于匹配文本框中的值。
// 注意,模式的开头和末尾不用加^和$符号(假定已经有了)
<input type="text" pattern="\d+" name="count">
使用 checkValidity()方法可以检测表单中的某个字段是否有效。所有表单字段都有个方法,如果字段的值有效,这个方法返回 true,否则返回 false。
if (document.forms[0].elements[0].checkValidity()){
//字段有效,继续
} else {
//字段无效
}
通过设置 novalidate 属性,可以告诉表单不进行验证。
<form method="post" action="signup.php" novalidate>
<!--这里插入表单元素-->
</form>
14.3 选择框脚本
选择框是通过<select>和<option>元素创建的。为了方便与这个控件交互,除了所有表单字段共 有的属性和方法外,HTMLSelectElement 类型还提供了下列属性和方法。
- add(newOption, relOption):向控件中插入新<option>元素,其位置在相关项(relOption)之前。
- multiple:布尔值,表示是否允许多项选择;等价于 HTML 中的 multiple 特性。
- options:控件中所有<option>元素的 HTMLCollection。
- remove(index):移除给定位置的选项。
- selectedIndex:基于 0 的选中项的索引,如果没有选中项,则值为-1。对于支持多选的控件,只保存选中项中第一项的索引。
- size:选择框中可见的行数;等价于 HTML 中的 size 特性。
选择框的 type 属性不是"select-one",就是"select-multiple",这取决于 HTML 代码中有没有 multiple 特性。
14.3.1 选择选项
对于只允许选择一项的选择框,访问选中项的最简单方式,就是使用选择框的 selectedIndex 属性.
var selectedOption = selectbox.options[selectbox.selectedIndex];
var selectedIndex = selectbox.selectedIndex;
var selectedOption = selectbox.options[selectedIndex];
14.3.2 添加选项
使用创建DOM的方式添加
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("Option text"));
newOption.setAttribute("value", "Option value");
selectbox.appendChild(newOption);
使用 Option 构造函数来创建新选项
var newOption = new Option("Option text", "Option value");
selectbox.appendChild(newOption); //在 IE8 及之前版本中有问题
使用选择框的 add()方法
var newOption = new Option("Option text", "Option value");
selectbox.add(newOption, undefined); //最佳方案
14.3.3 移除选项
使用 DOM 的 removeChild()方法,为其传入要移除的选项
selectbox.removeChild(selectbox.options[0]); //移除第一个选项
使用选择框的 remove()方法。这个方法接受一个参数,即要移除选项的索引
selectbox.remove(0); //移除第一个选项
将相应选项设置为 null
selectbox.options[0] = null; //移除第一个选项
14.3.4 移动和重排选项
如果为 appendChild()方法传入一个文档中已有的元素,那么就会先从该元素的父节点中移除它,再把它添加到指定的位置。
var selectbox1 = document.getElementById("selLocations1");
var selectbox2 = document.getElementById("selLocations2");
selectbox2.appendChild(selectbox1.options[0]);
14.4 表单序列化
表单序列化是将表单中的数据转换为字符串的过程。在 Web 开发中,当用户提交表单时,可以使用表单序列化将表单数据转换为可以在 HTTP 请求中传输的格式,通常是 URL 查询字符串或 JSON 格式。
14.5 富文本编辑
富文本编辑,又称为 WYSIWYG(What You See Is What You Get,所见即所得)。这一技术
的本质,就是在页面中嵌入一个包含空 HTML 页面的 iframe。通过设置 designMode 属性,这个空白 的 HTML 页面可以被编辑,而编辑对象则是该页面<body>元素的 HTML 代码。
designMode 属性有两个可能的值:"off"(默认值)和"on"。在设置为"on"时,整个文档都会变得可以编辑。
首先可以给 iframe 指定一个非常简单的 HTML 页面作为其内容来源
<!DOCTYPE html>
<html>
<head>
<title>Blank Page for Rich Text Editing</title>
</head>
<body>
</body>
</html>
要让它可以编辑,必须要将 designMode 设置为"on",但只有在页面完全加载之后才能设置这个属性。
<iframe name="richedit" style="height:100px;width:100px;" src="blank.htm"></iframe>
<script type="text/javascript">
EventUtil.addHandler(window, "load", function(){
frames["richedit"].document.designMode = "on";
});
</script>
14.5.1 使用contenteditable属性
可以把 contenteditable 属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。
<div class="editable" id="richedit" contenteditable></div>
14.5.2 操作富文本
与富文本编辑器交互的主要方式,就是使用 document.execCommand()。这个方法可以对文档执行预定义的命令,而且可以应用大多数格式。
document.execCommand()方法传递 3 个参数:要执行的命令名称、表示浏览器是否应该为当前命令提供用户界面的一个布尔值和执行命令必须的一个值(如果不需要值,则传递 null)。
14.5.3 富文本选区
使用框架(iframe)的 getSelection()方法,可以确定实际选择的文本。这个方法是 window 对象和 document 对象的属性,调用它会返回一个表示当前选择文本的 Selection对象。
14.5.4 表单与富文本
由于富文本编辑是使用 iframe 而非表单控件实现的,因此从技术上说,富文本编辑器并不属于表单。通常可以添加一个隐藏的表单字段,让它的值等于从 iframe 中提取出的 HTML。
form.addEventListener("submit", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.elements["comments"].value = frames["richedit"].document.body.innerHTML;
});
在此,我们通过文档主体的 innerHTML 属性取得了 iframe 中的 HTML,然后将其插入到了名为"comments"的表单字段中。