提交表单
用户单击提交按钮或图像按钮时,就会提交表单。使用<input>和<button>都可以定义提交按钮,只要将其type特性的值设置为"submit"即可,而图像按钮则是通过将<input>的
type特性设置为"image"来定义。
<input type="submit" vlaue="Submit Form"> --通用提交按钮
<button type="submit">Submit Form</button> --自定义提交按键
<input type="image" src="graphic.gif"/> --图像按钮
只要表单中存在上面列出的任何一种按钮,那么在相应的表单控件拥有焦点的情况下,按回车键就可以提交表单。(textarea是一个例外,在文本区中回车会换行。)
在JavaScript中,以编程方式调用submit()方法也可以提交表单。而且,这种方式无需表单包含提交按钮,任何时候都可以正常提交表单。
var from=document.getElementById("myForm");
//提交表单
form.submit();
在以调用submit()方法的形式提交表单时,不会觖submit事件,因此要记得在调用此方法之前先验证表单数据。
重置表单
在用户单击重置按键时,表单会被重置。使用type特性值为"reset"的<input>或<button>都可以创建重置按钮。如下面所示:
<input type="reset" vlaue="Reset Form"> --通用提交按钮
<button type="reset">Reset Form</button> --自定义提交按键
通过脚本重置
var from=document.getElementById("myForm");
//提交表单
form.reset();
表单字段
var form=document.getElementById("form1");
//取得表单中的第g个字段
var field1=from.elements[0];
//取得名为"textbox1"的字段
var field2=form.elements["textbox1"];
//取得表单中包含的字段的数量
var fieldCount=form.elements.length;
如果有多个表单控件都在使用一个name(如单选按钮),那么就会返回以该name命名的一个NodeList.
共有的表单字段方法
每个表单字段都有两个方法:focus(获得焦点)和blur(失去焦点);
自动切换焦点
为了增强易用性,同时加快数据输入,可以在前一个文本框中的字符达到最数量后,自动将焦点切换到下一个文本框。可以通过下列代码实现:
( function(){
function tabForward(event){
event=EventUtil.getEvent(event);
var target=EventUtil.getTarge(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);
}
)();
HTML中,表单是由<form>元素来表示的,而在javascript中,表单对应的则是HTMLFormElement类型,具有以下独有的属性和方法:
1. acceptCharset:服务器能够处理的字符集,等价于HTML中的accept-charset特性.
2. action:接受请求的URL,等价于HTML中的action特性.
3. elements:表单中所有控件的集合(HTMLCollection)
4. enctype:请求的编码类型;等价于HTML中的enctype特性.
5. length:表单中控件的数量.
6. method:要发送的HTTP请求类型,通常为get/post,等价于HTML的method特性.
7. name:表单的名称,等价于HTML的name特性.
8. reset():将所有表单域重置于默认值.
9. submit():提交表单
10. target:用于发送请求和接收响应的窗口,等价于HTML的target特性.
取得<form>元素引用的方式主要有以下两种.第一种通过getElementById:
var form = document.getElementById("form1");
第二种通过document.forms提取所有页面的表单,再通过数值索引或name值来取得特定的表单.
var firstForm = document.forms[0];//取得页面中的第一个表单
var myForm = document.forms["form2"];//取得页面中名称为"form2"的表单
不过第二种方式不推荐使用.因为一是容易出错,二是将来的浏览器可能不会支持.
1. 提交表单
用户单击提交按钮或图像按钮时,就会提交表单.使用<input>或<button>都可以定义提交按钮,只要将其type特性的值设置为"submit"即可,而图像按钮是通过将<input>的type特性值设置为"image"来定义:
<input type="submit" value="Submit Form" />
<button type="submit">Submit Form</button>
<input type="image" src="./smile.gif" />
界面显示如下:
我们可以编写如下代码来取消表单的提交:
var form = document.getElementById("myForm");
EventUtil.addHandler(form, "submit", function(event){
//取得事件对象
event = EventUtil.getEvent(event);
//阻止默认事件
EventUtil.preventDefault(event);
});
我们也可以使用编程的方式调用submit()方法来提交表单.而且,这种方式无需表单包含提交按钮,任何时候都可以正常提交表单:
var form = document.getElementById("myForm");
//提交表单
form.submit();
在以调用submit()方法的形式提交表单时,不会触发submit事件,因此要记得在调用此方法之前先验证表单数据.
提交表单会存在重复提交的情况,则有两种解决办法:提交表单后就禁止提交按钮,或者利用onsubmit事件处理程序取消后续的表单提交操作.
2. 重置表单
将type特性值设置为reset则可以重置表单(一般不推荐,通常是提供一个取消按钮来达到目标):
<!-- 通用重置按钮-->
<input type="reset" value="Reset Form" />
<!-- 自定义重置按钮-->
<button type="reset">Reset Form</button>
当点击重置按钮时,会触发reset事件:
<Form id="myForm">
<input type="reset" value="Submit Form" />
<button type="reset">Submit Form</button>
</form>
<body>
<script type="text/javascript">
var form = document.getElementById("myForm");
EventUtil.addHandler(form, "reset", function(event){
//取得事件对象
event = EventUtil.getEvent(event);
//阻止表单重置
EventUtil.preventDefault(event);
});
</script>
</body>
类似提交表单一样,我们也可以通过JavaScript来重置表单:
var form = document.getElementById("myForm");
//重置表单
form.reset();
3. 表单字段
每个表单都有elements属性,该属性是表单中所有表单元素的集合.这个elements集合是一个有序列表,其中包含着表单中的所有字段,例如<input>,<textarea>,<button>和<fieldset>.每个表单字段在elements集合中的顺序,与它们出现在标记中的顺序相同,可以按照位置和name特性来访问它们:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<form method="post" id="myForm">
<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>
</body>
<!--这里script脚本最好在body后面,而不是在head处,因为页面是顺序加载的-->
<script type="text/javascript">
var form = document.getElementById("myForm");
</script>
</html>
而firebug调试如下:
1. 共有的表单字段属性
1. disabled:布尔值,表示当前字段是否被禁用.
2. form:指向当前字段所属表单的指针;只读
3. name:当前字段的名称
4. readOnly:布尔值,表示当前字段是否可读
5. tabIndex:表示当前字段的切换(tab)序号.
6. type:当前字段的类型,如"checkbox"
7. value:提交给服务器的值.
除了form属性之外,可以通过JavaScript动态修改其他任何属性:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<form method="post" id="myForm">
<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>
</body>
<!--这里script脚本最好在body后面,而不是在head处,因为页面是顺序加载的-->
<script type="text/javascript">
var form = document.getElementById("myForm");
var field = form.elements[0];
//修改value属性
field.value = "other red";
//检查form属性的值
alert(field.form === form); //true
//把焦点设置到当前字段
field.focus();
//禁用当前字段
field.disabled = true;
//修改type属性(不推荐)
field.type = "checkbox";
</script>
</html>
而浏览器显示如下:
我们可以动态修改其属性(如禁用提交按钮--防止用户重复提交)
EventUtil.addHandler(form, "submit", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//取得提交按钮
var btn = target.elements["submit-btn"];
//禁用它
btn.disabled = true;
});
但是这里我们不能通过onclick事件处理程序来实现这个功能,因为不同浏览器存在"时差",有的浏览器会在触发表单的submit事件之前触发click事件,有些则相反.
除了<fieldset>之外,所有表单字段都有type属性,其值如下:
说明 HTML示例 type属性值
单选列表 <select>..</select> "select-one"
多选列表 <select multiple>...</select> "select-multiple"
自定义按钮 <button>...</button> "submit"
自定义非提交按钮 <button type="button">...</button> "button"
自定义重置按钮 <button type="reset">...</button> "reset"
自定义提交按钮 <button type="submit">...</button> "submit"
此外,<input>和<button>元素的type属性是可以动态修改的,而<select>元素的type属性则是只读的.
2. 共有的表单字段方法
而所有的表单字段都有两个方法:focus()和blur(),一个是聚焦,一个是移除焦点.其中,focus()方法用于将浏览器的焦点设置到表单字段,即激活表单字段,使其可以响应键盘事件.我们可以侦听load事件,在该事件发生时在表单的第一个字段上调用focus()方法:
EventUtil.addHandler(window, "load", function(event){
document.forms[0].elements[0].focus();
});
要注意的是,如果第一个表单字段是一个<input>元素,且其type特性的值为"hidden",那么上述代码会导致错误.另外,如果使用CSS的display和visibility属性隐藏了该字段,同样会导致错误.
HTML5为表单字段新增了一个autofocus属性.在支持这个属性的浏览器中,只要设置这个属性,不用JavaScript就能自动把焦点移动到相应字段:
<input type="text" autofocus>
为了autofocus能够正常的运行,需要进行以下的判断:
EventUtil.addHandler(window, "load", function(event){
var element = document.forms[0].elements[0];
if (element.autofocus !== true) {
element.focus();
}
});
与focus()方法相对的是blur()方法,它的作用是从元素中移走焦点.
document.forms[0].elements[0].blur();
3. 共有的表单字段事件
表单支持以下三个事件:
1. blur:当前字段失去焦点时触发.
2. change:对于<input>和<textarea>元素,在它们失去焦点且value值改变时触发;对于<select>元素,在其选项改变时触发.
3. focus:当前字段获得焦点时触发
以下示例为:检查用户的输入,输入非数字显示红色提示,输入正确的则显示蓝色背景:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<form method="post" id="myForm">
<div>
<li><input type="text" id="myNum" name="numbers"/></li>
</div>
</form>
</body>
<script type="text/javascript">
var forms = document.getElementById("myForm");
var textbox = forms["numbers"];
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);
var target = EventUtil.getTarget(event);
if (/[^\d]/.test(target.value)) {
target.style.backgroundColor = "red";
} else {
target.style.backgroundColor = "";
}
});
//这里不会时时触发change事件
EventUtil.addHandler(textbox, "change", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if (/[^\d]/.test(target.value)) {
target.style.backgroundColor = "red";
} else {
target.style.backgroundColor = "";
}
});
</script>
</html>
2. 文本框脚本
在HTML中,有两种方式来表现文本框,一种是使用<input>元素的单行文本框,一种是使用<textarea>的多行文本框.
设置<input>元素的type为"text"来表现文本框.设置size属性为能够显示的字符数,设置value特性来显示初始值,而maxlength特性则用指定文本框可以接受的最大字符数:
<input type="text" size="25" maxlength="50" value="initial value">
而对于<textarea>来说,通过设定rows和cols指定文本框的大小,而且初始值必须放在<textarea>和</textarea>之间
<textarea rows="25" cols="5">initial value</textarea>
它们的值也都保存在value中.
1. 选择文本
上述两种文本框都支持select()方法,这个方法用于选择文本框中的所有文本,而我们可以在文本框获得焦点时选择其所有文本:
var forms = document.getElementById("myForm");
var textbox = forms["numbers"];
//选择文本
textbox.select();
//在获取焦点时候选择文本
EventUtil.addHandler(textbox, "focus", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
1. 选择(select)事件
与select()方法对应的,是一个select事件.在选择了文本框中的文本时,就会触发select事件.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<form method="post" id="myForm">
<div>
<li><input type="text" id="myNum" name="numbers" value="123"/></li>
</div>
</form>
</body>
<script type="text/javascript">
var forms = document.getElementById("myForm");
var textbox = forms["numbers"];
//选择文本
textbox.select();
//这里不会时时触发change事件
EventUtil.addHandler(textbox, "select", function(event){
alert("Text selected " + textbox.value);
});
</script>
</html>
备注:这里就算是鼠标选择了部分的文本,textbox.value也是等于全部文本.
2. 取得选择的文本
通过select事件我们可以知道用户什么时候选择了文本,但仍然不知道用户选择了什么文本.HTML5添加了两个属性:selectionStart和selectionEnd,表示所选择文本的范围.但是对于IE8及更早的版本来说,需要通过document.selection来选择文本:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<form method="post" id="myForm">
<div>
<li><input type="text" id="myNum" name="numbers" value="123"/></li>
</div>
</form>
</body>
<script type="text/javascript">
var forms = document.getElementById("myForm");
var textbox = forms["numbers"];
//选择文本
textbox.select();
//这里不会时时触发change事件
EventUtil.addHandler(textbox, "select", function(event){
alert("Text selected " + getSelectedText(textbox));
});
function getSelectedText(textbox) {
if (typeof textbox.selectionStart == "number") {
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
} else {
return document.selection.createRange().text;
}
}
</script>
</html>
3. 选择部分文本
HTML5提供setSelectinRange()方法,此方法接收两个参数:要选择的第一个字符的索引和要选择的最后一个字符之后的字符的索引.但是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();
}
实例如下:
var forms = document.getElementById("myForm");
var textbox = forms["numbers"];
textbox.value = "hello world";
var value = selectText(textbox, 0, textbox.value.length);
//选择前3个字符
selectText(textbox, 0, 3);
//选择第4到第6个字符
selectText(textbox, 4, 7);
2. 过滤输入
1. 屏蔽字符
以下代码只允许用户输入数值:
EventUtil.addHandler(textbox, "keypress", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var charCode = EventUtil.getCharCode(event);
/*
* 1. !/\d/.test(String.fromCharCode(charCode))--正常屏蔽非数值
* 2. charCode > 9--屏蔽方向键
* 3. !event.ctrlKey--屏蔽ctrl
*/
if (!/\d/.test(String.fromCharCode(charCode)) && charCode > 9 && !event.ctrlKey) {
EventUtil.preventDefault(event);
}
});
2. 操作剪切板
HTML5定义了6个剪切板事件:
beforecopy:在发生复制操作前触发
copy:在发生复制操作触发
beforecut:在发生剪切操作前触发
cut:在发生剪切操作触发
beforepaste:在发生粘贴操作前触发
paste:在发生粘贴操作触发
要访问剪贴板中的数据,可以使用clipboardData对象:在IE中,这个对象是window对象的属性,而其他的浏览器为event对象的属性.
clipboardData对象有三个方法:getData(),setData()和clearData().由于IE浏览器的存在,则我们需要编写以下的代码:
getClipboardText: function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
},
setClipboardText: function(event, value){
if (event.clipboardData){
event.clipboardData.setData("text/plain", value);
} else if (window.clipboardData){
window.clipboardData.setData("text", value);
}
},
而我们可以判断所粘贴的数据是否符合预订的规则(如只能粘贴数值)
(function(){
var forms = document.getElementById("myForm");
var textbox = forms["numbers"];
EventUtil.addHandler(textbox, "paste", function(event){
event = EventUtil.getEvent(event);
var text = EventUtil.getClipboardText(event);
if (!/^\d*$/.test(text)){
EventUtil.preventDefault(event);
}
});
})();
3. 自动切换焦点
用户填写完当前字段后,自动将焦点切换到下一个字段,实例如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<form method="post" id="myForm">
<div>
<li><input type="text" id="txtTel1" name="tel1" maxlength="3" /></li>
<li><input type="text" id="txtTel2" name="tel2" maxlength="3" /></li>
<li><input type="text" id="txtTel3" name="tel3" maxlength="3" /></li>
</div>
</form>
</body>
<script type="text/javascript">
(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);
})();
</script>
</html>
4. HTML5约束验证API
通过浏览器进行验证而非JavaScript来验证:
1. required属性:必填字段
2. email和url属性:所输入的必须符合email或者url格式
3. 基于数值的几种类型:number,range,datetime,datetime-local,date,month,week,time(少使用)
4. pattern属性:使用正则表达式来过滤
5. 使用checkValidity()方法可以检测表单中的某个字段是否有效,有效则返回true.我们甚至可以在表单自身调用checkValidity()方法来检测整个表单是否有效:
if (document.form[0].elements[0].checkValidity()) {
//字段有效,继续
} else {
//字段无效
}
if (document.form[0].checkValidity()) {
//表单有效,继续
} else {
//表单无效
}
我们可以使用validity属性来查看为什么字段有效或者无效:
5.1. customError:如果设置了setCustomValidity(),则为true,否则为false
5. 2. patternMismatch:如果值与指定的pattern属性不匹配,则返回true
5. 3. rangeOverflow:如果值比max值大,返回true
5. 4. rangeUnderflow:如果值比min值小,返回true
5. 5. stepMisMatch:如果min和max之间的步长不合理,返回true
5. 6. tooLong:长度超过maxlength返回true
5. 7. typeMismatch:如果值不是mail或url要求的格式,返回true
5. 8. valid:代表无效
5. 9. valueMissing:如果标注为required的字段中没有值,返回true
实例如下:
if (input.validity && !input.validity.valid) {
if (input.validity.valueMissing) {
//
} else {
//
}
}
6. 禁用验证:通过设置 novalidate属性,可以告诉表单不进行验证.
如果一个表单中有多个提交按钮,为了指定点击某个提交按钮不必验证表单,可以在相应按钮上添加formnovalidate属性:
<form method="post" action="foo.php">
<input type="submit" value="Regular Submit"/>
<input type="submit" formnovalidate name="btnNoValidate" value="Non-validating Submit" />
</form>
整体实例如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<form method="post" id="myForm">
<div>
<li><input type="text" id="txtTel1" name="tel1" required/></li>
<li><input type="email" id="txtTel2" name="tel2" /></li>
<li><input type="number" id="txtTel3" name="tel3" min="0" max="100" step="5" /></li>
<li><input type="number" id="txtTel4" pattern="\d+" name="count"/></li>
<li><button type="submit" value="submit Form">Submit Form</button></li>
</div>
</form>
<form method="post" action="foo.php">
<input type="submit" value="Regular Submit"/>
<input type="submit" formnovalidate name="btnNoValidate" value="Non-validating Submit" />
</form>
</body>
<script type="text/javascript">
</script>
</html>
3. 选择框脚本
选择框是通过<select>和<option>元素创建的,HTMLSelectElement类型提供了额外的属性和方法:
1. add(newOption, relOption):向控件中插入新<option>元素,其位置在相关项(relOption)之前.
2. multiple:布尔值,表示是否允许多项选择,等价于HTML中的multiple特性.
3. options:控件中所有<option>元素的HTMLCollection
4. remove(index):移除给定位置的选项.
5. selectedIndex:基于0的选中项的索引,如果没有选中项,则值为-1.对于多选的空间,只保存选中项中第一项的索引.
6. size:选择框中可见的行数;等价于HTML中的size特性.
选择框的type属性不是"select-one",就是"select-multiple".而选择框中的value属性由当前选中项决定,相应规则是:
1. 没有选择,则为空字符串
2. 选中,则为<select>或者<option>中value的值
3. 否则,为文本的值
在DOM中,每个<option>元素都有一个HTMLOptionElement对象表示.为了便于访问数据,HTMLOptionElement对象添加了下列属性:
1. index:当前选项在options集合中的索引
2. label:当前选项的标签;等价于HTML中的label特性.
3. selected:布尔值,表示当前选项是否被选中.
4. text:选项的文本
5. value:选项的值
所以,我们不推荐使用DOM方法来访问这些信息:
var selectbox = document.forms[0].elements["location"];
var text = selectbox.options[0].firstChild.nodeValue;
var value = selectbox.options[0].getAttribute("value");
而推荐使用以下方法:
var selectbox = document.forms[0].elements["location"];
var text = selectbox.options[0].text;
var value = selectbox.options[0].value;
1. 选择选项
对于单选框,只要通过selectedIndex属性即可:
var selectedOption = selectbox.options[selectbox.selectedIndex];
实例如下:
<select name="location" id="selLocation" one>
<option value="aaa">aaa</option>
<option value="bbb">bbb</option>
<option value="ccc">ccc</option>
<option value="ddd">ddd</option>
</select>
而对于多选框,我们需要遍历选择框,然后一一进行判断:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<select name="location" id="selLocation" multiple>
<option value="aaa">aaa</option>
<option value="bbb">bbb</option>
<option value="ccc">ccc</option>
<option value="ddd">ddd</option>
</select>
<input type="button" value="Select first option" id="btnFirst">
</body>
<script type="text/javascript">
var btn1 = document.getElementById("btnFirst");
EventUtil.addHandler(btn1, "click", showSelected);
function getSelectedOptions(selectbox) {
var result = new Array();
var option = null;
for (var i = 0, len = selectbox.length; i < len; i++) {
option = selectbox.options[i];
if (option.selected) {
result.push(option);
}
}
return result;
}
function showSelected() {
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);
}
</script>
</html>
浏览器显示如下:
2. 添加选项
通常有三种方法,通过实例来验证:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<select name="location" id="selLocation" type="select-one">
<option value="aaa_value">aaa_text</option>
<option value="bbb_value">bbb_text</option>
<option value="ccc_value">ccc_text</option>
<option value="ddd_value">ddd_text</option>
</select>
</body>
<script type="text/javascript">
var selectbox = document.getElementById("selLocation");
//传统的DOM方法
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("eee_text"));
newOption.setAttribute("value", "eee_value");
selectbox.appendChild(newOption);
//使用Option构造函数方法
newOption = new Option("fff_text", "fff_value");
selectbox.appendChild(newOption);
//使用选择框的add方法--设置最后一个参数为undefined为了兼容各个浏览器
newOption = new Option("ggg_text", "ggg_value");
selectbox.add(newOption, undefined);
</script>
</html>
浏览器显示如下:
3. 移除选项
移除选项也通常有三种方法,通过实例来验证:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<select name="location" id="selLocation" type="select-one">
<option value="aaa_value">aaa_text</option>
<option value="bbb_value">bbb_text</option>
<option value="ccc_value">ccc_text</option>
<option value="ddd_value">ddd_text</option>
</select>
</body>
<script type="text/javascript">
var selectbox = document.getElementById("selLocation");
//DOM方法
selectbox.removeChild(selectbox.options[0]); //移除第一个选项
//选择框remove方法
selectbox.remove(0); //移除第一个选项
//浏览器遗留的方法,设置为null
selectbox.options[0] = null;
//移除所有选项
function clearSelectbox(selectbox) {
for (var i = 0, len = selectbox.options.length; i < len; i++) {
selectbox.remove(0);
}
}
clearSelectbox(selectbox);
</script>
</html>
4. 移动和重排选项
最佳方法是DOM的appendChild,insertBefore:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<select name="location1" id="selLocation1" type="select-one">
<option value="aaa_value">aaa_text</option>
<option value="bbb_value">bbb_text</option>
<option value="ccc_value">ccc_text</option>
<option value="ddd_value">ddd_text</option>
</select>
<select name="location2" id="selLocation2" type="select-one">
<option value="111_value">111_text</option>
<option value="222_value">222_text</option>
<option value="333_value">333_text</option>
<option value="444_value">444_text</option>
</select>
</body>
<script type="text/javascript">
var selectbox1 = document.getElementById("selLocation1");
var selectbox2 = document.getElementById("selLocation2");
//将第一个选择框中的第一个元素移动到第二个选择框中
selectbox2.appendChild(selectbox1.options[0]);
//将选中的项向前移动一个位置
var optionToMove = selectbox1.options[1];
selectbox1.insertBefore(optionToMove, selectbox1.options[optionToMove.index - 1]);
</script>
</html>
4. 表单序列化
通过函数说明一切:
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: //fieldset
case "file": //file input
case "submit": //submit button
case "reset": //reset button
case "button": //custom button
break;
case "radio": //radio button
case "checkbox": //checkbox
if (!field.checked){
break;
}
/* falls through */
default:
//don't include form fields without names
if (field.name.length){
parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
}
}
}
return parts.join("&");
}
5. 富文本编辑
富文本编辑WYSIWYG(What You See Is What You Get):在页面中嵌入一个包含空HTML页面的iframe,通过设置designMode属性,这个空白的HTML页面可以被编辑,而编辑的对象则是该页面<body>元素的HTML代码.designMode属性有两个可能的值:"off"(默认值)和"on",设置"on"时候可以进行编辑.
测试使用的tt.html:
<html>
<head>
<title>Blank page for rich text editing</title>
</head>
<body>
</body>
</html>
我们可以编写如下的代码:
<html>
<head>
<title>ContextMenu Event Example</title>
<script type="text/javascript" src="./EventUtil.js"></script>
</head>
<body>
<iframe name="richedit" style="height: 100px;width: 100px;" src="tt.html"></iframe>
</body>
<script type="text/javascript">
EventUtil.addHandler(window, "load", function(){
frames["richedit"].document.designMode = "on";
});
</script>
</html>
则浏览器显示如下:
关于富文本,书上提供了一个绝佳的例子:
<!DOCTYPE html>
<html>
<head>
<title>Rich Text Editing Example</title>
<script type="text/javascript" src="EventUtil.js"></script>
</head>
<body>
<form method="post" action="javascript:alert('Form submitted!')">
<div id="divSimple">
<input type="button" value="Bold">
<input type="button" value="Italic">
<input type="button" value="Underline">
<input type="button" value="Indent">
<input type="button" value="Outdent">
<input type="button" value="Copy">
<input type="button" value="Cut">
<input type="button" value="Paste">
</div>
<div id="divComplex">
<input type="button" value="Create Link" id="btnCreateLink">
<input type="button" value="Change Font Size" id="btnChangeFontSize">
<input type="button" value="Highlight Text" id="btnHighlight">
<input type="button" value="Get HTML" id="btnGetHtml">
<input type="button" value="Get Selected Text" id="btnGetSelected">
</div>
<div id="divQuery">Is the current selection:
<input type="button" value="Bold">
<input type="button" value="Italic">
<input type="button" value="Underline">
</div>
<iframe name="richedit" style="height: 100px; width: 300px" src="blank.htm"></iframe>
<input type="hidden" name="comments" value="">
<input type="submit" value="Submit Form">
</form>
<script type="text/javascript">
(function(){
EventUtil.addHandler(window, "load", function(){
frames["richedit"].document.designMode = "on";
});
var simple = document.getElementById("divSimple");
var complex = document.getElementById("divComplex");
var queryDiv = document.getElementById("divQuery");
EventUtil.addHandler(document.forms[0], "submit", function(){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.elements["comments"].value = frames["richedit"].document.body.innerHTML;
});
EventUtil.addHandler(simple, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if (target.type == "button"){
frames["richedit"].document.execCommand(target.value.toLowerCase(), false, null);
}
});
EventUtil.addHandler(complex, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "btnGetHtml":
alert(frames["richedit"].document.body.innerHTML);
break;
case "btnCreateLink":
var link = prompt("What link?", "http://www.wrox.com");
if (link){
frames["richedit"].document.execCommand("createlink", false, link);
}
break;
case "btnChangeFontSize":
var size = prompt("What size? (1-7)", "7");
if (size){
frames["richedit"].document.execCommand("fontsize", false, parseInt(size,10));
}
break;
case "btnGetSelected":
if (frames["richedit"].getSelection){
alert(frames["richedit"].getSelection().toString());
} else if (frames["richedit"].document.selection){
alert(frames["richedit"].document.selection.createRange().text);
}
break;
case "btnHighlight":
if (frames["richedit"].getSelection){
var selection = frames["richedit"].getSelection();
//get the range representing the selection
var range = selection.getRangeAt(0);
//highlight the selected text
var span = frames["richedit"].document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);
} else if (frames["richedit"].document.selection){
var range = frames["richedit"].document.selection.createRange();
range.pasteHTML("<span style=\"background-color:yellow\">" + range.htmlText + "</span>");
}
break;
}
});
EventUtil.addHandler(queryDiv, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if (target.type == "button"){
alert(frames["richedit"].document.queryCommandState(target.value.toLowerCase(), false, null));
}
});
})();
</script>
</body>
</html>
而浏览器的显示效果如下:
表单脚本
(一)表单的基础知识
1.提交表单
使用<input>或<button>将其type特性设置为submit后便可定义提交按钮,图片按钮通过将<input>的type特性值设置为"image"来定义。
使用preventDefault()方法阻止表单提交。一般在表单数据无效而不能发送给服务器时可以这么做。
//取得事件对象
event =EventUtil.getEvent(event);
//阻止默认事件
EventUtil.preventDefault(event);
以编程方式也可以提交表单,不会触发submit事件,因此提交前要验证表单数据。
重复提交表单:在第一次提交表单后就禁用提交按钮,或者利用onsubmit事件处理程序取消后续的表单提交操作。
2.重置表单
用户点击重置按钮时,会触发reset事件,我们可以在必要时取消重置操作。调用reset()方法回想单击重置按钮一样触发reset事件。
3.表单字段
每个表单都有elements属性,该属性是表单中所有表单元素的集合,可以按照位置和name特性来访问它们。
如果多个表单控件使用一个name,会返回该name的第一个NodeList。
①共有的表单字段属性
除了<fieldset>所有表单字段都有共同的一组属性。
能动态修改表单字段,意味着我们能在任何时候以任何方式动态操作表单。
//避免多次提及表单
EventUtil.addHandler(form, "submit", function(event){ event =EventUtil.getEvent(event); vartarget =EventUtil.getTarget(event); //取得提交按钮
varbtn = target.elements["submit-btn"]; //禁用它
btn.disabled = true;
不能用onclick事件处理程序实现因为有得浏览器会在触发表单的submit事件之前先触发click事件。
②共有的表单字段方法
每个表单字段都有两个方法:focus()和blur()。
focus方法用于将浏览器焦点设置到表单字段,使其可以响应键盘事件。
HTML5为表单字段新增了autofocus属性,把焦点移动到响应的字段。在支持的浏览器值为true。
<input type="text" autofocus>
Firefox4+、Safari5+、Chrome和Opera。
blur()是从元素移走焦点,不会把焦点转移到某个特定的元素上。
③公有的表单字段事件
除了支持鼠标、键盘、更改和HTML事件外,所有表单字段都支持者3个事件。
blur:子弹失去焦点时触发。
change:对<input>和<textarea>元素,在它们失去焦点且value值改变;对<select>元素,在其选项改变时触发。
focus:当前字段获得焦点。
可以使用focus事件修改文本框的背景颜色,以便更清楚表明字段获得焦点,可以利用blur事件恢复背景颜色,利用change事件在用户输入非数值字符时再次修改背景颜色。
(二)文本框脚本
文本框:一种是使用<input>元素的单行文本框,另一种是使用<textarea>的多行文本框。
文本框要将<input>元素的type特性设置为"text",size特性指定文本框能显示的字符数,value设置初始值,maxlength指定可接受最大字符数。
多行文本框用rows好cols分别指定行数和列数,<textarea>的初始值要放在<textarea>和</textarea>之间,且不能在HTML中给<textarea>指定最大字符数。
它们都会将用户输入的内容保存到value属性。
1.选择文本
select()方法用于选择文本框中所有文本,特别是文本框包含默认值时用户不用删除文本。
①选择事件
在IE9+、Opera、Firefox、Chrome和Safari中,只有用户选择了文本(而且释放鼠标),才会触发select事件在IE8及更早版本,只要用户选择一个字母(不必释放鼠标)就会触发。在调用select方法时也会触发select事件。
②取得选择的文本
添加属性selectionStart和selectionEnd可以获取选择的文本。这两个属性保存的是基于0的数值,表示所选择文本的范围。
textbox.value.substring(textbox.selectionStart, textbox.selectionEnd)
因为subString()方法基于字符串的偏移量操作,所以将selectionStart和selectionEnd直接传给它。
IE8及之前版本不支持这两个属性,它们有document.selection对象,保存着用户在整个文档选择的文本信息。与select事件一起用,并要创建一个范围再将文本提取出来。
document.selection.createRange().text;
③选择部分文本
setSelectionRange()方法,接收两个参数:要选择的第一个字符索引和最后一个字符之后的字符的索引。
要看到选择的文本,必须在调用setSelectionRange()之前或之后立即将焦点设置到文本框。
IE9、Firefox、Safari、Chrome和Opera支持。
IE8及之前版本支持使用范围选择部分文本。先使用createTextRange()方法创建一个范围,将其放在恰当的位置。再使用collapse()将范围折叠到文本框的开始位置,调用moveStart()和moveEnd()将范围移动到位。最后使用范围的select()范围选择文本。
2.过滤输入
①屏蔽字符
通过阻止事件的默认行为来屏蔽所有按键
EventUtil.addHandler(textbox, "keypress", function(event){ event =EventUtil.getEvent(event); EventUtil.preventDefault(event); });
屏蔽特定字符:
EventUtil.addHandler(textbox, "keypress", function(event){ event =EventUtil.getEvent(event); vartarget =EventUtil.getTarget(event); varcharCode = EventUtil.getCharCode(event); //跨浏览器取得字符编码
if(!/\d/.test(String.fromCharCode(charCode)) && charCode > 9 && !event.ctrlKey){ //fromCharCode将字符编码转换为字符串 !event.ctrlKey:没有按下Ctrl键
EventUtil.preventDefault(event); } });
②操作剪贴板
beforecopy copy beforecut cut beforepaste paste
要访问剪贴板的数据可以使用clipbordData对象:在IE这是window对象的属性,在Firefox 4+、Safari、Chrome里是相应event的属性。在Firefox、Safari和Chrome只有在处理剪贴板事件期间clipboardData对象才有效,在IE里可以随时访问clipboardData对象。
clipboardData对象有3个方法:getData()、setData()、clearData()。
getData()接收一个参数,即要取得的数据格式。IE有"text"和"URL",Firefox、Safari和Chrome里是MIME类型,但可以用"text"代表"text/plain"。
setData()第一个参数也是数据类型,Safari和Chrome只支持MIME类型,第二个参数是要放到剪贴板的文本。Safari和Chrome的setData()方法不能识别"text"类型,在成功放入脚本后返回true。
if(!/^\d*$/.test(text)){ EventUtil.preventDefault(event); }
并非所有浏览器支持访问剪贴板,更简单的做法是屏蔽一或多个剪贴板操作,在Opera需要阻止会触发这些事件的按键,还要阻止文本框显示上下文菜单。
3.自动切换焦点
functiontabForward(event){ event =EventUtil.getEvent(event); vartarget =EventUtil.getTarget(event); if(target.value.length ==target.maxLength){ varform =target.form; for(vari=0, len=form.elements.length; i < len; i++) { if(form.elements[i] ==target) { if(form.elements[i+1]){ form.elements[i+1].focus(); } return; } } } }
比较用户输入的值与文本框的maxlength特性,确定是否达到最大长度。如果相等则需要查找表单字段集合,直到找到下一个文本框。找到后将焦点切换到文本框。然后把这个函数指定为每个文本框的onkeyup事件处理程序。
4.HTML5约束验证API
HTML5新增了一些功能,即使javascript被禁用或没能加载也能确保基本的验证。Firefox 4+、Safari 5+、Chrome和Opera 10+支持。
①必填字段
第一种情况是在表单字段指定required属性
<input type="text" name="username" required>
适用于<input> <textarea> 和 <select>字段。
②其他输入类型
email和url属性
<input type = "email" name = "email"> <input type = "url" name = "homepage">
"email"属性要求输入的文本要符合电子邮件地址的模式,"url"要求输入的文本符合URL模式。但匹配模式存在问题。如果不给<input>元素设置required属性,空文本框也会通过验证。
③数据范围
"number" "range" "datetime" "tatetime-local" "date" "month" "week" "time",但浏览器支持不哈。
对所有这些数值类型的输入元素,可以指定min属性、max属性,和step属性。
stepUp()和stepDown(),接收一个可选参数:要在当前值基础加上或减去的数。
④输入模式
HTML5为文本增加了pattern属性,值是一个正则表达式,用于匹配文本框中的值。
//只允许输入数字
<input type="text" pattern="\d+" name="count">
指定pattern不能阻止用户输入无效的文本。
⑤检测有效性
checkValidity()方法可以检测表单中某个字段是否有效,如果字段有效返回true。字段值是否有效是根据前面的约束。要检测整个表单是否有效,可以在表单自身调用这个方法。
validity属性包含一系列属性,每个属性返回一个布尔值,说明该值是否符合约束。
⑥禁用验证
设置novalidate属性,表单不进行验证。
如果一个表单有多个提交按钮,为了指定点击某个提交按钮不验证表单,可以在相应的按钮上添加formnovalidate属性。
(三)选择框脚本
通过<select>和<option>创建。
HTMLSelectElement类型:
add(newOption,relOption):向插件插入新<option>元素,位置在relOption之前。
multiple:布尔值,是否允许多项选择。
options:所有<option>元素的HTMLCollection。
remove(index):移除指定位置的选项。
selectedIndex:基于0的选中项的索引。没有选中项值为-1。多项选择值保持选中项的第一项。
size:选择框中可见的行数。
选项框的value属性:
没有选中:空字符串。
有一个选中,而且value特性在HTML指定:等于value特性,即使value为空字符串。
有一个选中,value特性在HTML未指定:等于该项的文本。
有多个选中项:根据前两条规则取得第一个选中项的值。
HTMLOptionElement类型
index:当前选中在option的索引。
label:当前选项的标签。
selected:当前选项是否被选中、
text:选项的文本。
value:选项的值。
varselectbox = document.forms[0].elements["location"];
//推荐
vartext = selectbox.option[0].text; //选项的文本
vartext = selectbox.option[0].value; //选项的值
在未指定value特性时,IE会返回空字符串,IE9+、Safari、Firefox、Chrome和Opera返回与text特性相同的值。
1.选择选项
selectedIndex属性 访问选中项
varselectedOption = selectbox.option[selectbox.selectedIndex];
对选择多项的选择框,selectedIndex属性会取消以前的所有选项并选择指定的那一项。
另一种选择选项的方式——取得对某一项的引用,将其selected属性设置为true。在允许多项选择框设置不会取消对其他选项的选择。但在单选选择框中会取消。将selected设为false对单选选择框没有影响。
2.添加选项
方法一:DOM
创建<option>元素,为它添加文本节点,并设置器value特性,最后将它添加到选择框。
varnewOption = document.createElement("option"); newOption.appendChild(document.createTextNode(textTextbox.value)); newOption.setAttribute("value", valueTextbox.value); selectbox.appendChild(newOption);
方法二:option构造函数
接收两个参数text、value(可选)
varnewOption = newOption("Option text", "Option value"); selectbox.appendChild(newOption); //在IE8及之前版本有bug
方法三:选择框的add()方法
接收两个参数:要添加的新选项和将位于新选项之后的选项,第二个参数传入undefined可以在所有浏览器将新选项插入到列表最后。
varnewOption = newOption("Option text", "Option value"); selectbox.add(newOption, undefined);
3.移除选项
方法一:DOM的removeChild()方法
selectbox.removeChild(selectbox.option[0]);
方法二:选择框的remove()方法,接收一个参数:要移除选项的索引
selectbox.remove(0);
方法三:将相应选项设为null
selectbox.option[0] = null;
移除一个选项后后续选项会自动向上移一个位置。
4.移动和重排选项
将一个选项框的选项移动到另一个选项框——使用DOM的appendChild方法
selectbox2.appendChild(selectbox1.options[parseInt(textbox.value, 10)]);
将某一项移动到特定位置,最合适的DOM方法是insertBefore()
//在选项框中向前移动一个选项的位置
selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index-1]); //向后是Index+2
(四)表单序列化
利用type属性,连同name和value属性一起实现表单序列化。
(五)富文本编辑
本质是在页面嵌入一个包含空HTML页面的iframe。通过设置designMode属性,这个空白的HTML页面可以被编辑,编辑对象是该页面<body>元素的HTML代码。designMode属性值为on时,整个文档可编辑。
只有在页面加载完才能设置designMode属性,因此要用到onload事件。
1.使用contenteditable属性
可以把ontenteditable属性应用给页面上任何元素,用户便可以编辑该元素。有true、false、inherit三个可能的值。
IE、Firefox、Chrome、Safari和Opera
2.操作富文本
与富文本编辑器交互的主要方式是使用document.execCommand()。这个方法对文档执行预定义的命令,可以传递三个参数:要执行的命令名称,表示浏览器是否应该为当前命令提供用户界面的一个布尔值和执行命令必须的一个值(不需要则传递null)。为保持浏览器兼容性第二个参数设置为false。
与剪贴板相关的命令在不同浏览器差异很大。
这些命令产生的HTML在不同浏览器有很大不同。
queryCommandEnabled():检测是否可以针对当前选中的文本或者当前插入字符所在位置执行某个命令,接收一个参数即要检测的命令,如果允许执行这个命令则返回true。
queryCommandState():确定是否已将制定命令应用到了选中的文本。
queryCommandValue():取得执行命令时传入的值。
3.富文本选区
使用frame的getSelection()方法可以确定实际选择的文本。调用它会返回一个表示当前选择文本的Selection对象。
使用默认选区中的DOM范围,通过surroundContents()方法将选区添加到带有黄色背景的<span>元素。
varselection = frames["richedit"].getSelection(); //取得代表选区的范围
varrange = selection.getRangeAt(0); //突出显示选择的文本
varspan = frames["richedit"].document.createElement("span"); span.style.backgroundColor = "yellow"; range.surroundContents(span);
IE9、Firefox、Safari、Chrome、Opera 8都实现了它,IE8及之前版本可以通过selection对象操作选择的文本。
4.表单与富文本
富文本编辑器的HTML不会被自动提交给服务器,需要我们手工来提取并提交HTML。通常可以添加一个隐藏的表单字段,让它的值等于从iframe中提取出的HTML。
EventUtil.addHandler(document.forms[0], "submit", function(){ event =EventUtil.getEvent(event); vartarget =EventUtil.getTarget(event); target.elements["comments"].value = frames["richedit"].document.body.innerHTML; });
通过文档主体的innerHTML属性取得iframe的HTML,将其插入到"comments"的表单字段。如果想在代码中通过submit()手工提交表单必须这样做。
表单
①JavaScript中表单<form>对应HTMLFormElement类型。HTMLFormElement继承了HTMLElement,因而与其它HTML元素具有相同的默认属性。也有其独有属性和方法:
□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特性。
②获取表单
var form = document.getElementById("form1");
var firstForm = document.forms[0];
var myForm = document.forms["form2"];
1.1 提交表单
①提交表单的三种方法:
□通用按钮:<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);
});
③提交表单的最大问题是重复提交表单。解决办法:在第一次提交表单后就禁用提交按钮。
④在JavaScript中,可以以编程方式提交表单。
var form = document.getElementById("myForm");
//提交表单
form.submit(); //此方法提交表单不会触发submit事件
1.2 重置表单
①重置表单方式
□通用按钮:<input type="reset" value="Reset Form"/>
□自定义按钮:<button type="reset">Rest Form</button>
②用户单击重置按钮重置表单是,会触发reset事件,利用这个机会可在必要时取消重置操作。
③可用JavaScript重置表单:form.reset();与调用submit()方法不同,调用reset()方法会想单击重置按钮一样触发reset事件。
1.3表单字段
①访问表单字段方法:
□使用原生DOM方法。
□通过表单的elements属性,该属性是表单中所有元素的集合。
◇表单字段按标记顺序保存在elements中。
◇可以按照位置和name特性访问它们。
◇如果多个表单控件都使用一个name特性,则返回一个NodeList。
var form = document.getElementById("form1");
//取得表单中的第一个字段
var field1 = form.elements[0];
//取得名为textbox1的字段
var field2 = form.elements["textbox1"];
//取得表单中包含的字段的数量
var fieldCount = form.elements.length;
1.3.1 共有的表单字段属性
①表单字段共有的属性和方法如下:
□disabled:布尔值,表示当前字段是否被禁用。
□form:指向当前字段所属表单的指针,只读。
□name:当前字段的名称。
□readOnly:布尔值,表示当前字段是否只读。
□tabIndex:表示当前字段的切换(tab)序号。
□type:当前字段的类型,如:“checkbox”、“radio”等等。
□value:当前字段将被提交给服务器的值。
②不能用click事件处理submit事件,因不知道在submit前触发click还是submit后触发click。
1.3.2 共有的表单字段方法
□focus()方法:将浏览器的焦点设置到表单字段。
□blur()方法:从元素中移走焦点。
1.3.3 共有的表单字段事件
除了支持鼠标事件、键盘、变动和HTML事件外,所以表单字段支持下列3个事件:
□blur:当前字段失去焦点时触发。
□change:对于<input>和<textarea>元素,他们失去焦点切value值改变时触发;对于<select>元素,在其选项改变时触发。
□focus:当前字段获得焦点时触发。
2.文本框脚本
①在HTML中两种方法表现文本框
□使用<input>元素的单行文本框
◇显示25个字符,输入不超过50个字符。size="25" maxlength="50"
□<textarea>元素,多行文本框
◇25行,5列。rows="25" cols="5"
②设置文本框的值
□使用value属性读取或设置文本框的值,不建议使用DOM方法。
□使用DOM方法:setAttribute()设置value特性或修改<textarea>元素第一个子节点这样对value值的修改不一定反映到DOM中。
2.1 选择文本
①<input>单行文本和<textarea>多行文本都支持select()方法,这个方法用于选择文本框中所有文本。
EventUtil.addHandler(textbox, "focus", function(){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
2.1.1 选择(select)事件
select事件触发的情况复杂,要想编写跨浏览器代码,必须手工取得对事件目标的引用:
var textbox = document.forms[0].elements["textbox1"];
EventUtil.addHandler(textbox,"select",function(event){
var target = document.forms[0].elements["textbox1"];
alert("text selected");
});
2.1.2 取得选择的文本
□文本框的两个属性:selectionStart和selectionEnd。基于0的数值,表示所选文本范围。FF、Safari、Chrome、Opera支持。
□IE有一个document.select对象,其中保存用户整个文档范围内选择的文本信息。与select事件一起,可假定为文本内容。取值前须创建一个范围。
function getSelectedText(textbox){
if(document.selection){
return document.selection.createRange().text;
}else{
return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd);
}
}
2.1.3 选择部分文本
□setSelectionRange()方法。接受两个参数:要选择的第一个字符的索引和要选择的最后一个字符之后的字符索引。FF、Chrome、Safari、Opera支持。
□IE为文本框提供了createTextRange()方法,要选择文本框中的部分文本,必须首先使用这个方法创建一个范围,并将其放在恰当位置上。再使用moveStart()和moveEnd()这两个方法将范围移动位置。
□兼容代码
function selectText(textbox,strtIndex,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("charater",stopIndex-startIndex);
range.select();
}
Textbox.focus();
}
2.2.1 过滤输入
例为屏蔽非数字值,而不屏蔽ctrl组合键
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);
}
});
2.2.2 操作剪贴板
①6个剪贴板事件:
□beforecopy:在发生复制操作前触发;
□copy:在发生复制操作时触发
□beforecut:在发生剪切操作时触发。
□cut:在发生剪切操作时触发
□beforepaste:在发生粘贴操作前触发
□paste:在发生粘贴操作时触发
②访问剪贴板中数据,可使用clipboaredData对象,有3个方法:
getDate()、setDate()和clearData()
兼容方法:
var EventUtil = {
getClipboardText : function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
},
setClipboardText : function(event, value){
if(event.clipboardData){
return event.clipboardData.setData("text/pain",value);
}else if(window.clipboardData){
return window.clipboardData.setData("text",value);
}
},
};
3.选择框脚本
①选择框是通过<select>和<option>元素创建的。HTMLSelectElement类型还提供了下列属性和方法:
□add(newOption, relOption):向空间按中插入新元素,其位置在指定项relOption之前
□multiple:布尔值,表示是否允许多项选择;等价于HTML中的multiple特性。
□options:控件中所有<option>元素的HTMLCOllection。
□remove(index):移除给定位置选项。
□selectedIndex:基于0的选中项的索引,如果没有选中项,则值为-1.对于支持多选的控件,只保存选项中第一项的索引。
□size:选择框中可见的行数;等价于HTML中的size特性
□type:"select-one"或"select-multiple",取决于HTML代码中有没multiple特性。
□value:取决于当前选中项。
②DOM中,每个<option>元素都有一个HTMLOptionElement对象表示。其对象添加以下属性:
□index:当前选项在options集合中的索引
□label:当前选项的标签;等价于HTML中的label特性
□selected:布尔值,表示当前选项是否被选中。设true可选中。
□text:选项的文本
□value:选项的值(等价于HTML中的value特性)
3.1 选择选项
□对于只允许一项的选择框,使用选择框的selectedIndex属性。
var selectedOption = selectbox.options[selectbox.selectedIndex];
□对于多选的选择框,遍历检查其selected属性。
3.2 添加选项
①DOM方法:
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("Option text");
newOption.setAttribute("value","Option value");
selectbox.appendChild(newOption);
②Option构造函数,接受两个参数:文本(text)和值(value);第二个可选。(IE不可用)
Var newOption = new Option("Option text","Option value");
Selectbox.appendChild(newOption); //在IE中有问题
③使用选择框的add()方法,接受两个参数:要添加的新选项和将位于新选项之后的选项。
Var newOption = new Option("Option text", "Option value");
Selectbox.add(newOption, undefined); //最佳方案
3.3 移除选项
①可使用DOM的removeChild()方法,为其传入要移除的项。
selectbox.removeChild(selectbox.option[0]);
②使用选择框的remove()方法。接受一个参数,即要移除项的索引。
selectbox.remove(0); //移除第一个选项
③将相应项设为null
3.4 移动和重排选项
①使用appendChild()方法,讲一个选择框中选项移到另一个选择框。
②使用insertBefore()实现重排
4.表单序列化
①浏览器发数据至服务器方式:
□对表单字段的名称和值进行URL编码,使用和号(&)分隔。
□不发送禁用的表单字段
□只发送勾选的复选框和单选按钮
□不发送type为“reset”和“button”的按钮。
□多选选择框中的每个选中值单独一个条目。
□在单击提交按钮表单的情况下,也会发送提交按钮;否则,不发送提交按钮。也包括type为"image"的<input>元素。
□<select>元素的值,就是选中<option>元素的value特性的值。如果<option>元素没有value特性,则是<option> 元素的文本值。
②表单序列化代码:
function serialize(form){
var parts = new Array();
var field = null;
for(var i = 0, len = form.elements.length; i < len; i++){
field = form.elements[i];
switch(field.type){
case "select-one" :
case "select-multiple" :
for(var j=0, optLen = field.options.length; j<optLen; j++){
var option = field.options[j];
if(option.selected){
var optValue=" ";
if(potion.hasAttribue){
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));
}
case undefined : //字段集
case "file" : //文件输入
case "submit" : //提交按钮
case "reset" : //自定义按钮
Break;
case "radio" : //单选按钮
case "checkbox" : //复选框
If(!field.checked){break;}
default :
parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.name));
return parts.join("&");
}
}
}
5.富文本编辑(略)
javascript--14表单脚本
猜你喜欢
转载自zhyp29.iteye.com/blog/2304411
今日推荐
周排行