web前端之JavaScript高级程序设计七:表单脚本
表单的基础知识:
在 HTML 中,表单是由form元素来表示的,而在 JavaScript 中,表单对应的则是 HTMLFormElement 类型。 HTMLFormElement 继承了 HTMLElement,因而与其他 HTML 元素具有相同的默认属性。不过, 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 特性。
提交表单:
用户单击提交按钮或图像按钮时,就会提交表单。使用input或button都可以定义提交按钮,只要将其 type 特性的值设置为”submit”即可,而图像按钮则是通过将input的 type 特性值设置为”image”来定义的。因此,只要我们单击以下代码生成的按钮,就可以提交表单。
<!-- 通用提交按钮 -->
<input type="submit" value="Submit Form">
<!-- 自定义提交按钮 -->
<button type="submit">Submit Form</button>
<!-- 图像按钮 -->
<input type="image" src="graphic.gif">
只要表单中存在上面列出的任何一种按钮,那么在相应表单控件拥有焦点的情况下,按回车键就可以提交该表单。(textarea 是一个例外,在文本区中回车会换行。)如果表单里没有提交按钮,按回车键不会提交表单。
重置表单:
在用户单击重置按钮时,表单会被重置。使用 type 特性值为”reset”的input或button都
可以创建重置按钮,如下面的例子所示。
<!-- 通用重置按钮 -->
<input type="reset" value="Reset Form">
<!-- 自定义重置按钮 -->
<button type="reset">Reset Form</button>
这两个按钮都可以用来重置表单。在重置表单时,所有表单字段都会恢复到页面刚加载完毕时的初始值。如果某个字段的初始值为空,就会恢复为空;而带有默认值的字段,也会恢复为默认值。用户单击重置按钮重置表单时,会触发 reset 事件。利用这个机会,我们可以在必要时取消重置操作。
表单字段:
可以像访问页面中的其他元素一样,使用原生 DOM 方法访问表单元素。此外,每个表单都有elements 属性,该属性是表单中所有表单元素(字段)的集合。这个 elements 集合是一个有序列表,其中包含着表单中的所有字段,例如input、 textarea、 button和fieldset。每个表单字段在 elements 集合中的顺序,与它们出现在标记中的顺序相同,可以按照位置和 name 特性来访问它们。下面来看一个例子。
var form = document.getElementById("form1");
//取得表单中的第一个字段
var field1 = form.elements[0];
//取得名为"textbox1"的字段
var field2 = form.elements["textbox1"];
//取得表单中包含的字段的数量
var fieldCount = form.elements.length;
对应的属性:
disabled:布尔值,表示当前字段是否被禁用。
form:指向当前字段所属表单的指针;只读。
name:当前字段的名称。
readOnly:布尔值,表示当前字段是否只读。
tabIndex:表示当前字段的切换(tab)序号。
type:当前字段的类型,如”checkbox”、 “radio”,等等。
value:当前字段将被提交给服务器的值。对文件字段来说,这个属性是只读的,包含着文件在计算机中的路径。
共有的表单字段事件:
除了支持鼠标、键盘、更改和 HTML 事件之外,所有表单字段都支持下列 3 个事件。
blur:当前字段失去焦点时触发。
change:对于input和textarea元素,在它们失去焦点且 value 值改变时触发;对于select元素,在其选项改变时触发。
focus:当前字段获得焦点时触发。
通常,可以使用 focus 和 blur 事件来以某种方式改变用户界面,要么是向用户给出视觉提示,要么是向界面中添加额外的功能(例如,为文本框显示一个下拉选项菜单)。而 change 事件则经常用于验证用户在字段中输入的数据。例如,假设有一个文本框,我们只允许用户输入数值。此时,可以利用focus 事件修改文本框的背景颜色,以便更清楚地表明这个字段获得了焦点。可以利用 blur 事件恢复文本框的背景颜色,利用 change 事件在用户输入了非数值字符时再次修改背景颜色。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>表单脚本</title>
<script type="text/javascript">
window.onload=function(){
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: function (element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
},
getEvent: function (event) {
return event ? event : window.event;
},
getTarget: function (event) {
return event.target || event.srcElement;
},
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubbles = true;
}
},
getRelatedTarget: function (event) {
if (event.relatedTarger) {
return event.relatedTarget;
} else if (event.toElement) {
return event.toElement;
} else if (event.fromElement) {
return event.fromElement;
} else { return null; }
}
};
var textbox=document.forms[0].elements[0];
EventUtil.addHandler(textbox,"focus",function(event){
event=EventUtil.getEvent(event);
var target=EventUtil.getTarget(event);
if(target.style.backgroundColor !="red"){
target.style.backgroundColor ="yellow";
}
});
EventUtil.addHandler(textbox,"blur",function(event){
event=EventUtil.getEvent(event);
target=EventUtil.getTarget(event);
if(/^\d{11}$/.test(target.value)){
target.style.backgroundColor="red";
}else{
target.style.backgroundColor="";
}
});
EventUtil.addHandler(textbox,"change",function(event){
event=EventUtil.getEvent(event);
var target=EventUtil.getTarget(event);
if(/^\d{11}$/.test(target.value)){
target.style.backgroundColor="red";
}else{
target.style.backgroundColor="";
}
});
};
</script>
</head>
<body>
<form>
<input type="text">
</form>
</body>
</html>
正则表达式
用于判断里面的字符是不是全是数字,并且是11位数字。
文本框脚本:
在 HTML 中,有两种方式来表现文本框:一种是使用input元素的单行文本框,另一种是使用textarea的多行文本框。这两个控件非常相似,而且多数时候的行为也差不多。
要表现文本框,必须将input元素的 type 特性设置为”text”。而通过设置 size 特性,可以指定文本框中能够显示的字符数。通过 value 特性,可以设置文本框的初始值,而 maxlength 特性则用于指定文本框可以接受的最大字符数。
相对而言,textarea元素则始终会呈现为一个多行文本框。要指定文本框的大小,可以使用 rows和 cols 特性。其中, rows 特性指定的是文本框的字符行数,而 cols 特性指定的是文本框的字符列数(类似于inpu元素的 size 特性)。与input元素不同, textarea的初始值必须要放在textarea和textarea之间,如下面的例子所示:
<textarea rows="25" cols="5">initial value</textarea>
选择文本:
上述两种文本框都支持 select()方法,这个方法用于选择文本框中的所有文本。在调用 select()方法时,大多数浏览器(Opera 除外)都会将焦点设置到文本框中。这个方法不接受参数,可以在任何时候被调用。
在文本框获得焦点时选择其所有文本,这是一种非常常见的做法,特别是在文本框包含默认值的时候。因为这样做可以让用户不必一个一个地删除文本。下面展示了实现这一操作的代码。
EventUtil.addHandler(textbox, "focus", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
过滤输入:
我们经常会要求用户在文本框中输入特定的数据,或者输入特定格式的数据。例如,必须包含某些字符,或者必须匹配某种模式。由于文本框在默认情况下没有提供多少验证数据的手段,因此必须使用JavaScript 来完成此类过滤输入的操作。而综合运用事件和 DOM 手段,就可以将普通的文本框转换成能够理解用户输入数据的功能型控件。
屏蔽字符:
如果只想屏蔽特定的字符,则需要检测 keypress 事件对应的字符编码,然后再决定如何响应。例如,下列代码不允许用户输入数值。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>文本框脚本</title>
<script type="text/javascript">
window.onload=function(){
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: function (element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
},
getEvent: function (event) {
return event ? event : window.event;
},
getTarget: function (event) {
return event.target || event.srcElement;
},
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubbles = true;
}
},
getRelatedTarget: function (event) {
if (event.relatedTarger) {
return event.relatedTarget;
} else if (event.toElement) {
return event.toElement;
} else if (event.fromElement) {
return event.fromElement;
} else { return null; }
}
};
var textbox=document.forms[0].elements[0];
EventUtil.addHandler(textbox,"keypress",function(event){
event=EventUtil.getEvent(event);
target=EventUtil.getTarget(event);
if (/\d/.test(target.value)) {
EventUtil.preventDefault(event);
}
});
};
</script>
</head>
<body>
<form>
<input type="text">
</form>
</body>
</html>
自动切换焦点:
使用 JavaScript 可以从多个方面增强表单字段的易用性。其中,最常见的一种方式就是在用户填写完当前字段时,自动将焦点切换到下一个字段。通常,在自动切换焦点之前,必须知道用户已经输入了既定长度的数据(例如电话号码)。
为增强易用性,同时加快数据输入,可以在前一个文本框中的字符达到最大数量后,自动将焦点切换到下一个文本框。换句话说,用户在第一个文本框中输入了 3 个数字之后,焦点就会切换到第二个文本框,再输入 3 个数字,焦点又会切换到第三个文本框。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<script type="text/javascript">
window.onload=function(){
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: function (element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
},
getEvent: function (event) {
return event ? event : window.event;
},
getTarget: function (event) {
return event.target || event.srcElement;
},
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubbles = true;
}
},
getRelatedTarget: function (event) {
if (event.relatedTarger) {
return event.relatedTarget;
} else if (event.toElement) {
return event.toElement;
} else if (event.fromElement) {
return event.fromElement;
} else { return null; }
}
};
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);
};
</script>
</head>
<body>
<form>
<input type="text" name="tel1" id="txtTel1" maxlength="3">
<input type="text" name="tel2" id="txtTel2" maxlength="3">
<input type="text" name="tel3" id="txtTel3" maxlength="4">
</form>
</body>
</html>
选择框脚本:
选择框是通过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 特性。选择框的 value 属性由当前选中项决定,相应规则如下。
如果没有选中的项,则选择框的 value 属性保存空字符串。
如果有一个选中项,而且该项的 value 特性已经在 HTML 中指定,则选择框的 value 属性等于选中项的 value 特性。即使 value 特性的值是空字符串,也同样遵循此条规则。
如果有一个选中项,但该项的 value 特性在 HTML 中未指定,则选择框的 value 属性等于该项的文本。
如果有多个选中项,则选择框的 value 属性将依据前两条规则取得第一个选中项的值。
在DOM中,每个option元素都有一个HTMLOptionElement对象表示。为便于访问数据,HTMLOptionElement 对象添加了下列属性:
index:当前选项在 options 集合中的索引。
label:当前选项的标签;等价于 HTML 中的 label 特性。
selected:布尔值,表示当前选项是否被选中。将这个属性设置为 true 可以选中当前选项。
text:选项的文本。
value:选项的值(等价于 HTML 中的 value 特性)
富文本编辑:
富文本编辑,又称为 WYSIWYG(What You See Is What You Get,所见即所得)。在网页中编辑富文本内容,是人们对 Web 应用程序最大的期待之一。虽然也没有规范,但在 IE 最早引入的这一功能基础上,已经出现了事实标准。而且, Opera、 Safari、 Chrome 和 Firefox 都已经支持这一功能。这一技术的本质,就是在页面中嵌入一个包含空 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>
这个页面在 iframe 中可以像其他页面一样被加载。要让它可以编辑,必须要将 designMode 设置为”on”,但只有在页面完全加载之后才能设置这个属性。因此,在包含页面中,需要使用 onload 事件处理程序来在恰当的时刻设置 designMode,如下面的例子所示:
<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>
在富文本编辑器中,使用框架(iframe)的 getSelection()方法,可以确定实际选择的文本。
这个方法是 window 对象和 document 对象的属性,调用它会返回一个表示当前选择文本的 Selection对象。每个 Selection 对象都有下列属性。
anchorNode:选区起点所在的节点。
anchorOffset:在到达选区起点位置之前跳过的 anchorNode 中的字符数量。
focusNode:选区终点所在的节点。
focusOffset: focusNode 中包含在选区之内的字符数量。
isCollapsed:布尔值,表示选区的起点和终点是否重合。
rangeCount:选区中包含的 DOM 范围的数量。
Selection对象的这些属性并没有包含多少有用的信息。好在,该对象的下列方法提供了更多信息,并且支持对选区的操作。
addRange(range):将指定的 DOM 范围添加到选区中。
collapse(node, offset):将选区折叠到指定节点中的相应的文本偏移位置。
collapseToEnd():将选区折叠到终点位置。
collapseToStart():将选区折叠到起点位置。
containsNode(node):确定指定的节点是否包含在选区中。
deleteFromDocument():从文档中删除选区中的文本,与document.execCommand(“delete”,false, null)命令的结果相同。
extend(node, offset):通过将 focusNode 和 focusOffset 移动到指定的值来扩展选区。
getRangeAt(index):返回索引对应的选区中的 DOM 范围。
removeAllRanges():从选区中移除所有 DOM 范围。实际上,这样会移除选区,因为选区中至少要有一个范围。
reomveRange(range):从选区中移除指定的 DOM 范围。
selectAllChildren(node):清除选区并选择指定节点的所有子节点。
toString():返回选区所包含的文本内容。