第十六篇 表单脚本

by caix in 深圳

表单的基础知识

在 HTML 中,表单是由 <form> 元素来表示的,而在 JavaScript 中,表单对应的则是 HTMLFormElement 类型

HTMLFormElement 具有下列独有的属性和方法
acceptCharset:服务器能够处理的字符集;等价于 HTML 中的 accept-charset 特性
action:接受请求的 URL;等价于 HTML 中的 action 特性
elements:表单中所有控件的集合
enctype:请求的编码类型;等价于 HTML 中的 enctype 特性
length:表单中控件的数量
method:要发送的 HTTP 请求类型,通常是"get"或"post";等价于 HTML 的 method 特性
name:表单的名称;等价于 HTML 的 name 特性
reset():将所有表单域重置为默认值
submit():提交表单
target:用于发送请求和接收响应的窗口名称;等价于 HTML 的 target 特性
获取表单
1、通过 document.getElementById() 与其他元素一样
2、通过 document.forms 通过集合的方式获取,可以通过 数值索引 或 name值 获取表单
var firstForm = document.forms[0];
=> 获取页面中的第一个表单
var myForm = document.forms["form2"];
=> 获取页面中 name属性值 为 form2 的表单
提交表单
1、通过提交按钮或图像按钮提交表单
在表单中使用 <input> 或者 <button> 标签,并将其 type属性 设置为submit,图像按钮则是将 <input> 的type属性设置为 image
以这种方式提交表单时,浏览器将请求发送给服务器之前会触发 submit事件
并可以验证表单是否提交,不提交的话通过阻止该事件的默认行为取消提交表单。如下:
<input type = "submit" value = "提交表单">
<button type = "submit" value = "提交表单">
<input type = "image" src = "...">
var form = document.getElementById("myForm");
EventUtil.addHandler(form , "submit" , function(event) {
event = EventUtil.getEvent(event); => 取得事件对象
EventUtil.preventDefault(event); => 阻止默认行为,取消提交表单
})
2、调用submit() 方法提交表单
这种方法无需提交按钮,任何时候都可以提交表单,但是调用 submit() 方法的时候,不会触发 submit事件
所以要在调用 submit() 方法之前验证表单
var form = document.getElementById("myForm");
form.submit();
重置表单
1、使用 type值 为 reset 的 <input><button>
用户单击重置按钮时,会触发 reset事件,因此可以取消重置操作
<input type = "reset" value = "重置表单">
<button type = "reset" value = "重置表单">
var form = document.getElementById("myForm");
EventUtil.addHandler(form , "reset" , function({
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event); => 阻止表单重置
}))
2、使用表单的 reset() 方法
调用 reset() 方法时,也会触发 reset事件
var form = document.getElementById("myForm");
form.reset();
表单字段

每个表单都有elements 属性,是表单中所有表单元素(字段)的有序列表

可以按照位置和 name 特性来访问表单中的字段

var form = document.getElementById("form1");
=> 取得表单中的第一个字段
var field1 = form.elements[0];
=> 取得 name 为 textbox1 的字段
var field2 = form.elements["textbox1"];
=> 取得表单中包含的字段的数量
var fieldCount = form.elements.length;
1、表单共有的字段属性
disabled:布尔值,表示当前字段是否被禁用
form:指向当前字段所属表单的指针;只读
name:当前字段的名称
readOnly:布尔值,表示当前字段是否只读
tabIndex:表示当前字段的切换(tab)序号
type:当前字段的类型,如"checkbox""radio",等等
value:当前字段将被提交给服务器的值。对文件字段来说,这个属性是只读的,包含着文在计算机中的路径
2、表单共有的字段方法
focus() :将浏览器的焦点设置到表单字段
blur() :移出元素的焦点
3、表单共有的字段事件
blur:当前字段失去焦点时触发
change:对于 <input>和<textarea> 元素,在它们失去焦点且 value 值改变时触发;对 <select> 元素,在其选项改变时触发
focus:当前字段获得焦点时触发

文本框脚本

选择脚本

文本框的 select() 方法用于选择文本框中所有文本,没有参数

1、选择事件
用户选择文本的时候,会触发 select 事件
2、取得选择的全部文本
使用 selectionStart 和 selectionEnd 两个属性可以取得所选文本
function getSelectedText (textbox) {
return textbox.value.substring(textbox.selectionStart , textbox.selectionEnd);
}
3、取得选择的部分文本 setSelectionRange () 方法
使用 setSelectionRange () 方法获得所选的部分文本,该方法接收两个参数
第一个字符的索引
最后一个字符的索引
0开始算,不包括最后一个字符索引
textbox.value = "Hello World!";
textbox.setSelectionRange(0 , textbox.value.length); => "Hello World!"
textbox.setSelectionRange(0 , 3); => 前3个字符——"Hel"
过滤输入
1、屏蔽字符
只允许输入数值
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、操作剪贴板
6个剪贴板事件
beforecopy:在发生复制操作前触发
copy:在发生复制操作时触发
beforecut:在发生剪切操作前触发
cut:在发生剪切操作时触发
beforepaste:在发生粘贴操作前触发
paste:在发生粘贴操作时触发
clipboardData 对象可以访问剪贴板中的数据
getData():接收一个参数,要取得的数据类型
setData():接收两个参数,数据类型、要放在剪贴板中的文本
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/plain", value);
} else if (window.clipboardData){
return window.clipboardData.setData("text", value);
}
},
//省略的代码
};
自动切换焦点
可以在前一个文本框中的字符达到最大数量后,自动将焦点切换到下一个文本框
HTML5 约束验证 API
1、必填字段
在 DOM 元素中添加 required 属性
任何带有 required属性 的字段都必须有值,否则无法提交表单
此属性适用于 <input>、<textarea> 和 <select> 字段
<input type="text" name="username" required>
=> 通过JS检测对应元素的 required属性 来判断表单字段是否为必填
let isRequired = document.forms[0].elements['username'].required;
=> 检测浏览器是否支持 required属性
let isRequiredSupported = 'required' in document.createElement('input');
2、新增类型
HTML5为 <input>元素 增加了几个新的 type值
其中两个得到广泛支持的'email''url',二者都有浏览器提供的自定义验证
<input type="email" name="email">
<input type="url" name="homepage">
浏览器在匹配模式时都存在问题,最明显的是文本"-@-"会被认为是有效的电子邮件地址
对于这两个新类型,除非应用了required属性,否则空字段是有效的
除了以上两种 type,还有数值类型的:
number
range
datetime
datetime-local
date
month
week
time
并非所有主流浏览器都支持这些类型,因此使用时要当心
且这些数值类型,都可以指定 min属性 和 max属性,以及 step属性
每个属性在JS中也可以通过对应元素的 DOM属性 来访问和修改
还有两个方法从当前值加上或减去对应的数值:
stepUp(num)
stepDown(num)
input.stepUp(); => 加 1
input.stepUp(5); => 加 5
input.stepDown(); => 减 1
input.stepDown(10); => 减 10
3、输入模式
HTML5 为文本字段新增了 pattern 属性。这个属性的值是一个正则表达式,用于匹配文本框中的值
限制只能输入数字
<input type="text" pattern="\d+" name="count">
与新增的输入类型一样,指定 pattern属性 也不会阻止用户输入无效内容
模式会应用到值,然后浏览器会知道值是否有效
4、检测有效性
使用 checkValidity()方法 可以检测表单中的某个字段是否有效,如果字段的值有效,这个方法返回 true,否则返回 false
=> 检查字段是否有效
if(document.forms[0].elements[0].checkValidity()) {
// 有效
} else {
// 无效
}
=> 检查整个表单是否有效
if(document.forms[0].checkValidity()) {
// 表单有效,继续
} else {
// 表单无效
}
heckValidity()方法 只会告诉我们字段是否有效
而 validity属性 会告诉我们字段为什么有效或无效。这个属性是一个对象,包含一系列返回布尔值的属性
通过 validity属性 可以检查表单字段的有效性,从而获取更具体的信息
if(input.validity && !input.validity.valid) {
if(input.validity.valueMissing){
console.log('Please specify a value');
}
}
5、禁用验证
通过设置 novalidate 属性,可以告诉表单不进行验证
<form method="post" action="/signup" novalidate>
...
</form>
=> 这个值也可以通过JS属性noValidate检索或设置
=> 关闭验证
document.forms[0].noValidate = true;
如果一个表单中有多个提交按钮,为了指定点击某个提交按钮不必验证表单,可以在相应的按钮上添加 formnovalidate 属性
<form method="post" action="/signup">
<input type="submit" formnovalidate name="btnNoValidate" value="Non-validating submit">
</form>
=> 关闭验证
document.forms[0].elements['btnNoValidate'].formNoValidate = true;

选择框脚本

选择框是使用 <select> 和 <option> 元素创建的

HTML Select Element类型 额外提供以下属性和方法
add(newOption, relOption) 在 relOption 之前向控件中添加新的option
multiple 布尔值,表示是否允许多选
options 控件中所有 <option>元素 的 HTMLCollection
remove(index) 移除给定位置的选项
selectedIndex 选中项基于0的索引值。如果没有选中项则为 -1。对于允许多选的列表,始终是第一个选项的索引
size 选择框中可见的行数。
每个 <option> 元素在 DOM 中都由一个 HTMLOptionElement对象 表示,此类型为方便数据存取添加了以下属性:
index 选项在options集合中的索引
label 选项的标签,等价于HTML的label属性
selected 布尔值,表示是否选中了当前选项。
要取得所有选中项,需要循环选项集合逐一检测 selected 属性
text 选项的文本
value 选项的值
在操作选项时,最好使用特定于选项的属性,因为这些属性得到了跨浏览器的良好支持
选择框的 change事件 与其他表单字段是不一样的
其他表单字段会在自己的值改变后触发 change事件,然后字段失去焦点
而选择框会在选中一项时立即触发 change事件
选择选项
对于单选的选择框,访问选中项可以使用选择框的 selectedIndex 属性,也可以利用选项的 selected 属性为 true
let selectedOption = selectbox.options[selectbox.selectedIndex];
selectbox.options[0].selected = true;
对于多选的选择框,访问选择框的 selectedIndex 属性只能获取第一个选中项,访问选项的 selected 属性为 true 可以获取所有的选中项
添加选项

有两种方式

1、使用 Option 构造函数创建选项,接收两个参数:文本(text)、值(value),第二个参数可选,兼容 DOM 的浏览器会返回一个 <option> 元素
let newOption = new Option("Option text", "Option value");
selectbox.appendChild(newOption); => 在 IE8 及之前版本中有问题
2、使用选择框的 add() 方法,接收两个参数:要添加的新选项、位于新选项之后的选项,第二个参数设置为null表示在列表的最后添加一个选项
let newOption = new Option("Option text", "Option value");
selectbox.add(newOption, undefined); => 最佳方案,undefined可以兼容IE
移除选项

有两种方式

1、利用选择框的 remove() 方法移除选项,接收一个参数: 要移除选项的索引
selectbox.remove(0); => 移除第一个选项
2、利用将选项设置为 null 可以移除选项
selectbox.options[0] = null; => 移除第一个选项
移动和重排选项

appendChild() 方法会从其父元素移除然后插入指定位置

insertBefore() 插入到指定位置

移动选项
let selectbox1 = document.getElementById("selLocations1");
let selectbox2 = document.getElementById("selLocations2");
selectbox2.appendChild(selectbox1.options[0]);
重排选项
let optionToMove = selectbox.options[1];
selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index-1]);

表单序列化

字段名和值是 URL 编码的并以和号(&)分隔。
禁用字段不会发送。
复选框或单选按钮只在被选中时才发送。
类型为"reset""button"的按钮不会发送。
多选字段的每个选中项都有一个值。
通过点击提交按钮提交表单时,会发送该提交按钮;否则,不会发送提交按钮。类型为"image"的<input>元素视同提交按钮。
<select>元素的值是被选中<option>元素的 value 属性。如果<option>元素没有 value 属性,则该值是它的文本。

富文本编辑

原理
在空白 HTML 文件中嵌入一个 iframe。通过 designMode 属性设置为on,将这个空白文档变成可编辑的
方法
方式一
页面嵌入一个包含空 HTML 页面的 iframe 。通过设置 designMode 属性,这个空白的 HTML 页面可以被编辑,而编辑对象则是该页面 <body> 元素的 HTML 代码。designMode 属性有两个可能的值:"off"(默认值)和 "on"。"on"表示整个文档可以编辑。
方式二
把 contenteditable 属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。
与富文本交互
document.execCommand()
document.execCommand()
三个参数
要执行的命令
表示浏览器是否为命令提供用户界面的布尔值 (始终false
执行命令必须的值

2f5f4334c9d610a6ed2289f218ef02e7.png

eefb012e2a05baf987d2f0b0664f3e7a.png

queryCommandEnabled()
用于确定当前选中文本或光标所在位置是否可以执行相关命令
queryCommandState()
确定相关命令是否应用到了当前文本选区
queryCommandValue()
返回执行命令时使用的值
富文本选择
getSelection()
可以获得富文本编辑器的选区
返回的对象有以下属性
anchorNode:选区开始的节点。
anchorOffset:在 anchorNode 中,从开头到选区开始跳过的字符数。
focusNode:选区结束的节点。
focusOffset:focusNode 中包含在选区内的字符数。
isCollapsed:布尔值,表示选区起点和终点是否在同一个地方。
rangeCount:选区中包含的 DOM 范围数量。
返回的对象有以下方法
addRange(range):把给定的 DOM 范围添加到选区。
collapse(node, offset):将选区折叠到给定节点中给定的文本偏移处。
collapseToEnd():将选区折叠到终点。
collapseToStart():将选区折叠到起点。
containsNode(node):确定给定节点是否包含在选区中。
deleteFromDocument():从文档中删除选区文本。与执行 execCommand("delete", false, null)命令结果相同。
extend(node, offset):通过将 focusNode 和 focusOffset 移动到指定值来扩展选区。
getRangeAt(index):返回选区中指定索引处的 DOM 范围。
removeAllRanges():从选区中移除所有 DOM 范围。这实际上会移除选区,因为选区中至少要包含一个范围。
removeRange(range):从选区中移除指定的 DOM 范围。
selectAllChildren(node):清除选区并选择给定节点的所有子节点。
toString():返回选区中的文本内容。
示例
var selection = frames["richedit"].getSelection();
取得选择的文本
var selectedText = selection.toString();
取得代表选区的范围
var range = selection.getRangeAt(0);
突出显示选择的文本
var span = frames["richedit"].document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);
posted @   caix-1987  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示