第14章 表 单 脚 本
取得
<form>
元素引用的方式有好几种。其中最常见的方式就是将它看成与其他元素一样,并为其
添加id 特性,然后再像下面这样使用getElementById()方法找到它。
var form = document.getElementById(“form1”);
其次,通过document.forms 可以取得页面中所有的表单。在这个集合中,可以通过数值索引或
name 值来取得特定的表单,如下面的例子所示。
var firstForm = document.forms[0]; //取得页面中的第一个表单
var myForm = document.forms[“form2”]; //取得页面中名称为”form2”的表单用户单击提交按钮或图像按钮时,就会提交表单。使用或都可以定义提交按钮,
只要将其type 特性的值设置为”submit”即可,而图像按钮则是通过将的type 特性值设置为
“image”来定义的。因此,只要我们单击以下代码生成的按钮,就可以提交表单。
<!-- 通用提交按钮 -->
<input type="submit" value="Submit Form">
<!-- 自定义提交按钮 -->
<button type="submit">Submit Form</button>
<!-- 图像按钮 -->
<input type="image" src="graphic.gif">
以这种方式提交表单时,浏览器会在将请求发送给服务器之前触发submit 事件。这样,我们就有
机会验证表单数据,并据以决定是否允许表单提交。阻止这个事件的默认行为就可以取消表单提交。例
如,下列代码会阻止表单提交。
var form = document.getElementById(“myForm”);
EventUtil.addHandler(form, “submit”, function(event){
//取得事件对象
event = EventUtil.getEvent(event);
//阻止默认事件
EventUtil.preventDefault(event);
});
这里使用了第13 章定义的EventUtil 对象,以便跨浏览器处理事件。调用prevetnDefault()
方法阻止了表单提交。一般来说,在表单数据无效而不能发送给服务器时,可以使用这一技术。
在JavaScript 中,以编程方式调用submit()方法也可以提交表单。而且,这种方式无需表单包含
提交按钮,任何时候都可以正常提交表单。来看一个例子。
var form = document.getElementById(“myForm”);
//提交表单
form.submit();
在以调用submit()方法的形式提交表单时,不会触发submit 事件,因此要记得在调用此方法之
前先验证表单数据。解决重复提交的的办法有两个:在第一次提交表单后就禁用提交按钮,或者利用onsubmit 事件处理程序取消后续的表单提交操作。
重置表单
<!-- 通用重置按钮 -->
<input type="reset" value="Reset Form">
<!-- 自定义重置按钮 -->
<button type="reset">Reset Form</button>
最常见的解决方案,就是在第一次单击后就禁用提交按钮。只要侦听submit 事件,并在该事件
发生时禁用提交按钮即可。以下就是这样一个例子。
//避免多次提交表单
EventUtil.addHandler(form, "submit", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//取得提交按钮
var btn = target.elements["submit-btn"];
//禁用它
btn.disabled = true;
});每个表单字段都有两个方法:focus()和 blur()
HTML5 为表单字段新增了一个autofocus 属性。在支持这个属性的浏览器中,只要设置这个属性,
不用JavaScript 就能自动把焦点移动到相应字段。例如:
<input type="text" autofocus>
所有表单字段都支持下列3 个事件。
blur:当前字段失去焦点时触发。
change:对于<input>
和<textarea>
元素,在它们失去焦点且value 值改变时触发;对于
<select>
元素,在其选项改变时触发。
focus:当前字段获得焦点时触发。在文本框获得焦点时选择其所有文本,这是一种非常常见的做法,特别是在文本框包含默认值的时
候。因为这样做可以让用户不必一个一个地删除文本。下面展示了实现这一操作的代码。
EventUtil.addHandler(textbox, “focus”, function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
要取得用户在文本框中选择的文本,可以使用如下代码。
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;
}
}过滤输入
EventUtil.addHandler(textbox, "keypress", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var charCode = EventUtil.getCharCode(event);
if (!/\d/.test(String.fromCharCode(charCode)) && charCode > 9 &&
!event.ctrlKey){
EventUtil.preventDefault(event);
}
});自动切换焦点
为增强易用性,同时加快数据输入,可以在前一个文本框中的字符达到最大数量后,自动将焦点切
换到下一个文本框。换句话说,用户在第一个文本框中输入了3 个数字之后,焦点就会切换到第二个文
本框,再输入3 个数字,焦点又会切换到第三个文本框。这种“自动切换焦点”的功能,可以通过下列
代码实现:
(function(){
function tabForward(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if (target.value.length == target.maxLength){
var form = target.form;
for (var 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;
}
}
}
}
var textbox1 = document.getElementById(“txtTel1”);
var textbox2 = document.getElementById(“txtTel2”);
var textbox3 = document.getElementById(“txtTel3”);
EventUtil.addHandler(textbox1, “keyup”, tabForward);
EventUtil.addHandler(textbox2, “keyup”, tabForward);
EventUtil.addHandler(textbox3, “keyup”, tabForward);
})();要取得所有选中的项,可以循环遍历选项集合,然后测试每个选项的selected 属性。来看下面的例子。
function getSelectedOptions(selectbox){
var result = new Array();
var option = null;
for (var i=0, len=selectbox.options.length; i < len; i++){
option = selectbox.options[i];
if (option.selected){
result.push(option);
}
}
return result;
}
这个函数可以返回给定选择框中选中项的一个数组。首先,创建一个将包含选中项的数组,然后使
用for 循环迭代所有选项,同时检测每一项的selected 属性。如果有选项被选中,则将其添加到
result 数组中。最后,返回包含选中项的数组。下面是一个使用getSelectedOptions()函数取得
选中项的示例。
var selectbox = document.getElementById(“selLocation”);
var selectedOptions = getSelectedOptions(selectbox);
var message = “”;
for (var i=0, len=selectedOptions.length; i < len; i++){
message += “Selected index: ” + selectedOptions[i].index +
“\nSelected text: ” + selectedOptions[i].text +
“\nSelected value: ” + selectedOptions[i].value + “\n\n”;
}
alert(message);添加选项
第三种添加新选项的方式是使用选择框的add()方法。DOM 规定这个方法接受两个参数:要添加
的新选项和将位于新选项之后的选项。如果想在列表的最后添加一个选项,应该将第二个参数设置为
null。在IE 对add()方法的实现中,第二个参数是可选的,而且如果指定,该参数必须是新选项之后
选项的索引。兼容DOM 的浏览器要求必须指定第二个参数,因此要想编写跨浏览器的代码,就不能只
传入一个参数。这时候,为第二个参数传入undefined,就可以在所有浏览器中都将新选项插入到列
表最后了。来看一个例子。
var newOption = new Option(“Option text”, “Option value”);
selectbox.add(newOption, undefined); //最佳方案移除选项
selectbox.removeChild(selectbox.options[0]); //移除第一个选项
selectbox.remove(0); //移除第一个选项
selectbox.options[0] = null; //移除第一个选项
要清除选择框中所有的项,需要迭代所有选项并逐个移除它们,如下面的例子所示:
function clearSelectbox(selectbox){
for(var i=0, len=selectbox.options.length; i < len; i++){
selectbox.remove(i);
}
}
这个函数每次只移除选择框中的第一个选项。由于移除第一个选项后,所有后续选项都会自动向上
移动一个位置,因此重复移除第一个选项就可以移除所有选项了。表单序列化
function serialize(form){
var parts = [],
field = null,
i,
len,
j,
optLen,
option,
optValue;
for (i=0, len=form.elements.length; i < len; i++){
field = form.elements[i];
switch(field.type){
case “select-one”:
case “select-multiple”:
if (field.name.length){
for (j=0, optLen = field.options.length; j < optLen; j++){
option = field.options[j];
if (option.selected){
optValue = “”;
if (option.hasAttribute){
optValue = (option.hasAttribute(“value”) ?
option.value : option.text);
} else {
optValue = (option.attributes[“value”].specified ?
option.value : option.text);
}
parts.push(encodeURIComponent(field.name) + “=” +
encodeURIComponent(optValue));
}
}
}
break;
case undefined: //字段集
case “file”: //文件输入
case “submit”: //提交按钮
case “reset”: //重置按钮
case “button”: //自定义按钮
break;
case “radio”: //单选按钮
case “checkbox”: //复选框
if (!field.checked){
break;
}
/* 执行默认操作 */
default:
//不包含没有名字的表单字段
if (field.name.length){
parts.push(encodeURIComponent(field.name) + “=” +
encodeURIComponent(field.value));
}
}
}
return parts.join(“&”);
}另一种编辑富文本内容的方式是使用名为contenteditable 的特殊属性,这个属性也是由IE 最
早实现的。可以把contenteditable 属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。
这种方法之所以受到欢迎,是因为它不需要iframe、空白页和JavaScript,只要为元素设置
contenteditable 属性即可。
<div class="editable" id="richedit" contenteditable></div>