目录
表单的基础知识
在 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 特性。
///取得<form>元素
var form = document.getElementById("form1");
var firstForm = document.forms[0]; //取得页面中的第一个表单
var myForm = document.forms["form2"]; //取得页面中名称为"form2"的表单
提交表单
<!-- 通用提交按钮 -->
<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提交表单,不会触发submit事件,因此要记得在调用此方法之前先验证表单数据。
var form = document.getElementById("myForm");
//提交表单
form.submit();
重置表单
<!-- 通用重置按钮 -->
<input type="reset" value="Reset Form">
<!-- 自定义重置按钮 -->
<button type="reset">Reset Form</button>
用户单击重置按钮重置表单时,会触发 reset 事件。利用这个机会,可以在必要时取消重置操作。
var form = document.getElementById("myForm");
EventUtil.addHandler(form, "reset", function(event){
//取得事件对象
event = EventUtil.getEvent(event);
//阻止表单重置
EventUtil.preventDefault(event);
});
//通过 JavaScript 来重置表单,调用 reset()方法会像单击重置按钮一样触发 reset 事件
var form = document.getElementById("myForm");
//重置表单
form.reset();
表单字段
每个表单都有elements 属性,该属性是表单中所有表单元素(字段)的集合。这个 elements 集合是一个有序列表,其中包含着表单中的所有字段,例如<input>、 <textarea>、 <button>和<fieldset>。每个表单字段在 elements 集合中的顺序,与它们出现在标记中的顺序相同,可以按照位置和 name 特性来访问它们。
var form = document.getElementById("form1");
//取得表单中的第一个字段
var field1 = form.elements[0];
//取得名为"textbox1"的字段
//如果有多个表单控件都在使用一个 name(如单选按钮),那么就会返回以该 name 命名的一个NodeList
var field2 = form.elements["textbox1"];
//取得表单中包含的字段的数量
var fieldCount = form.elements.length;
共有的表单字段属性
除了<fieldset>元素之外,所有表单字段都拥有相同的一组属性。表单字段共有的属性如下。
disabled:布尔值,表示当前字段是否被禁用。
form:指向当前字段所属表单的指针;只读。
name:当前字段的名称。
readOnly:布尔值,表示当前字段是否只读。
tabIndex:表示当前字段的切换(tab)序号。
type:当前字段的类型,如"checkbox"、 "radio",等等。
value:当前字段将被提交给服务器的值。对文件字段来说,这个属性是只读的,包含着文件在计算机中的路径
var form = document.getElementById("myForm");
var field = form.elements[0];
//修改 value 属性
field.value = "Another value";
//检查 form 属性的值
alert(field.form === form); //true
//把焦点设置到当前字段
field.focus();
//禁用当前字段
field.disabled = true;
//修改 type 属性(不推荐,但对<input>来说是可行的)
field.type = "checkbox";
不能通过 onclick 事件处理程序来实现一些功能,原因是不同浏览器之间存在“时差”:有的浏览器会在触发表单的 submit 事件之前触发 click 事件,而有的浏览器则相反。对于先触发 click 事件的浏览器,意味着会在提交发生之前禁用按钮,结果永远都不会提交表单。因此,最好是通过 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()。focus()方法用于将浏览器的焦点设置到表单字段,即激活表单字段,使其可以响应键盘事件。blur()方法,它的作用是从元素中移走焦点。在调用 blur()方法时,并不会把焦点转移到某个特定的元素上;仅仅是将焦点从调用这个方法的元素上面移走而已。
共有的表单字段事件
除了支持鼠标、键盘、更改和 HTML 事件之外,所有表单字段都支持下列 3 个事件。
blur:当前字段失去焦点时触发。
change:对于<input>和<textarea>元素,在它们失去焦点且 value 值改变时触发;对于
<select>元素,在其选项改变时触发。
focus:当前字段获得焦点时触发
文本框脚本
<input type="text" size="25" maxlength="50" value="initial value">
<textarea rows="25" cols="5">initial value</textarea>
选择文本
上述两种文本框都支持 select()方法,这个方法用于选择文本框中的所有文本。在调用 select()方法时,大多数浏览器(Opera 除外)都会将焦点设置到文本框中。这个方法不接受参数,可以在任何时候被调用。
var textbox = document.forms[0].elements["textbox1"];
textbox.select();
//在文本框获得焦点时选择其所有文本
EventUtil.addHandler(textbox, "focus", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
选择(select)事件
var textbox = document.forms[0].elements["textbox1"];
EventUtil.addHandler(textbox, "select", function(event){
var alert("Text selected" + textbox.value);
});
取得选择的文本
//取得用户在文本框中选择的文本
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
}
选择部分文本
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();
}
textbox.value = "Hello world!"
//选择所有文本
selectText(textbox, 0, textbox.value.length); //"Hello world!"
//选择前 3 个字符
selectText(textbox, 0, 3); //"Hel"
//选择第 4 到第 6 个字符
selectText(textbox, 4, 7); //"o w"
过滤输入
屏蔽字符
//屏蔽所有按键操作
EventUtil.addHandler(textbox, "keypress", function(event){
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
});
//只允许用户输入数值
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);
}
});
操作剪贴板
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/plain", value);
} else if (window.clipboardData){
return window.clipboardData.setData("text", value);
}
},
//省略的代码
};
自动切换焦点
使用 JavaScript 可以从多个方面增强表单字段的易用性。其中,最常见的一种方式就是在用户填写完当前字段时,自动将焦点切换到下一个字段。
<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">
(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);
})();
HTML5 约束验证API
必填字段
<input type="text" name="username" required>
var isUsernameRequired = document.forms[0].elements["username"].required;
var isRequiredSupported = "required" in document.createElement("input");
其他输入类型
<input type="email" name ="email">
<input type="url" name="homepage">
var input = document.createElement("input");
input.type = "email";
var isEmailSupported = (input.type == "email");
数值范围
<!--只能输入 0 到 100 的值,而且这个值必须是 5 的倍数-->
<input type="number" min="0" max="100" step="5" name="count">
输入模式
<!--只允许在文本字段中输入数值-->
<input type="text" pattern="\d+" name="count">
检测有效性
//使用 checkValidity()方法可以检测表单中的某个字段是否有效。
if (document.forms[0].elements[0].checkValidity()){
//字段有效,继续
} else {
//字段无效
}
//validity属性可说明为什么字段有效或无效
if (input.validity && !input.validity.valid){
if (input.validity.valueMissing){
alert("Please specify a value.")
} else if (input.validity.typeMismatch){
alert("Please enter an email address.");
} else {
alert("Value is invalid.");
}
}
禁用验证
<form method="post" action="signup.php" novalidate>
<!--这里插入表单元素-->
</form>
选择框脚本
选择选项
//用选择框的 selectedIndex 属性
var selectedIndex = selectbox.selectedIndex;
var selectedOption = selectbox.options[selectedIndex];
alert("Selected index: " + selectedIndex + "\nSelected text: " +
selectedOption.text + "\nSelected value: " + selectedOption.value);
///取得对某一项的引用,然后将其 selected 属性设置为 true///
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;
}
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);
添加选项
//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); //最佳方案
移除选项
//DOM 的 removeChild()方法
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(i);
}
}
移动和重排选项
//将第一个选择框中的第一个选项移动到第二个选择框
var selectbox1 = document.getElementById("selLocations1");
var selectbox2 = document.getElementById("selLocations2");
selectbox2.appendChild(selectbox1.options[0]);
//在选择框中向前移动一个选项的位置
var optionToMove = selectbox.options[1];
selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index-1]);
//将选择框中的选项向后移动一个位置
var optionToMove = selectbox.options[1];
selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index+2]);
表单序列化
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("&");
}
富文本编辑