表单的基础知识
HTML中是<form>元素表示,JS中表单对应的是HTMLFormElement类型,其继承了HTMLElement,具有其他HTML元素具有的默认属性
HTMLFormElement独有的属性和方法:
取得<form>元素的引用方式:
常用的方式:将其看成与其他元素一样,并且添加id特性,再使用getElementById()方法找到
var form = document.getElementById("form1");
通过document.forms取得页面中所有的表单,可以通过数值索引或者name值来取得特定的表单
可以同时设置id和name属性,值不一定相同
提交表单
点击提交按钮或者图像按钮就会提交表单
使用<input>或<button>可以定义提交按钮,只需要将其type特性的值设置为“sumit”即可,而图像按钮通过将<input>的type特性值设置为“image”来定义
点击以下代码生成的按钮就可以提交表单
响应表单空间拥有焦点(即光标闪烁),按回车键就可以提交表单
先触发submit事件,可以判断是否允许表单提交,之后浏览器会将请求发送给服务器
组织事件的默认行为可以取消表单的提交
JS中,以编程的方式调用submit()方法可以提交表单
此方法不需要表单包含提交按钮,任何时候都可以正常提交表单
调用此方法提交表单不会触发submit事件,需要事先进行验证表单
避免出现问题的解决方案:
在第一次提交表单后就禁用提交按钮
利用 onsubmit 事件处理程序取消后续的表单提交操作
重置表单
点击重置按钮时,表单会进行重置
使用type特性值为"reset"的<input>或<button>都可以创建重置按钮
某个字段初始值为空,就恢复为空;带有默认值的字段,就会恢复默认值
用户点击重置按钮表单时候,就会触发reset事件
阻止重置操作的进行
reset()方法与submit()方法不同,调用reset()方法会像点击重置按钮一样触发reset事件
可能出现的问题的解决方法:
常见的做法是提供一个取消按钮,让用户能够回到前一个页面,而不是不分青红皂白地重置表单中的所有值
表单手段
使用原生DOM方法访问表单元素
每个表单都有elements属性,该属性是所有表单元素字段的集合
elements集合是一个有序列表,包含表单中所有的字段
字段:<input>、<textarea>、<button>和<fieldset>
每个表单字段在elements集合中有顺序,与他们出现在标记中的顺序相同,可以根据位置以及name特性来访问它们
若表单控件同时使用同一个name(如单选按钮),那么就会返回以name命名的一个NodeList,访问可以通过数组元素的顺序来访问
通过访问表单的属性来访问元素,例如 form[0]可以取得第一个表单字 段,而 form["color"]则可以取得第一个命名字段。这些属性与通过 elements 集 合访问到的元素是相同的
通过表单属性访 问元素只是为了与旧浏览器向后兼容而保留的一种过渡方式
共有的表单字段属性(除了fieldset元素)
除了form属性,其余都可以通过JS动态修改其他任何属性
解决重复点击表单的提交按钮:常见的解决方案,就是在第一次单击后就禁用提交按钮。只要侦听 submit 事件,并在该事件发生时禁用提交按钮
注意:不能通过 onclick 事件处理程序来实现这个功能,原 因是不同浏览器之间存在“时差”:有的浏览器会在触发表单的 submit 事件之前触发 click 事件, 而有的浏览器则相反
type属性
对于<input>元素,这个值等于HTML特性type的值
其他元素,type属性的值:
共有的表单字段事件
支持鼠标、键盘、更改和HTML事件以及blur、change、focus
用户改变当前字段的焦点,或者调用blur()或focus()方法时,都可以触发blur和focus事件
注意:change事件在不同的表单控件中触发的次数有不同之处
<input>和<textarea>元素获得焦点到失去焦点并且value值改变的时候才触发change事件
<select>元素,用户选择不同的选项,就触发change事件
blur与change的没有触发顺序的先与后
文本框脚本
现文本框:一种是使用<input>元素的单行文本框,另一种是使用 <textarea>的多行文本框
<input>和<textarea>
<input>与<textarea>的一些区别
input无需尾标签,而textarea需要
<textarea>不能在HTML中指定最大字符数
可以用value属性读取或者设置文本框的值(比较推荐)
使用标准的DOM方法,不要使用 setAttribute()设置<input>元素的 value 特性,也不要去修改<textarea> 元素的第一个子节点(不建议)
选择文本
两种文本框都支持select()方法,用于选择文本框的所有文本,不接受参数,可以在任何时候调用
选择(select)事件
触发:选择了文本框中的文本时候触发
在 IE9+、Opera、Firefox、Chrome 和 Safari中,只有用户选择了文本(而且要释放鼠标),才会触发 select 事件。而在 IE8及更早版本中,只要用户选择了一个字母(不必释放鼠标),就会触发 select 事件。另外,在调用 select()方法时也 会触发 select 事件
取得选择的文本
HTML5添加一些扩展方案来解决问题,通过添加两个属性:selectionStart和selectionEnd。
取得用户在文本框中选择的文本:
substring()方法基于字符串的偏移量执行操作
IE8之前的方案:
document.selection 对象,其中保存着用户在整个文档范围内选择的文本信息
选择部分文本
最早Firefox引入的setSelectionRange()方法
这个方法接收两个参数:要选择的第一个字符的索引和要选择的后一个字符之后的字符的索引
要选择文本框中的部分文本,必须 首先使用 IE 在所有文本框上提供的 createTextRange()方法创建一个范围,并将其放在恰当的位置 上。然后,再使用 moveStart()和 moveEnd()这两个范围方法将范围移动到位。不过,在调用这两个 方法以前,还必须使用 collapse()将范围折叠到文本框的开始位置。此时,moveStart()将范围的起 点和终点移动到了相同的位置,只要再给 moveEnd()传入要选择的字符总数即可。后一步,就是使 用范围的 select()方法选择文本
selectText()函数接收三个参数:要操作的文本框、要选择文本中第一个字符的索引和要选 择文本中后一个字符之后的索引
过滤输入
屏蔽字符
响应向文本框中插入字符操作的是 keypress 事件,可以通过阻止这个事件的默认行为来屏蔽此类字符
只允许输入数值
为了让代码更通用(避免其他键触发keypress事件影响测试),只要不屏蔽那些字符编码小于10的键即可
添加一个检测条件,以确保用户没有按 Ctrl键(服务于赋值】粘贴以及其他操作)
操作剪贴板
6个剪贴板事件:
在 Safari、Chrome和 Firefox 中,beforecopy、beforecut 和 beforepaste 事件只会在显示针对文本框的上下文菜单(预期将发 生剪贴板事件)的情况下触发。但是,IE则会在触发 copy、cut 和 paste 事件之前先行触发这些事件。 至于 copy、cut 和 paste 事件,只要是在上下文菜单中选择了相应选项,或者使用了相应的键盘组合 键,所有浏览器都会触发它们
访问剪贴板中的数据,可以使用 clipboardData 对象
在 IE中,这个对象是 window 对象的 属性;而在 Firefox 4+、Safari和 Chrome中,这个对象是相应 event 对象的属性
clipboardData 对象有三个方法:getData()、setData()和 clearData()
getData()从剪贴板中取得数据,接受一个参数:取得数据的格式
在 IE中,有两种数据格式:"text" 和"URL"。在 Firefox、Safari 和 Chrome 中,这个参数是一种 MIME 类型;不过,可以用"text"代表 "text/plain"
setData()第一个参数是数据类型,第二个参数是要放在剪贴板中的文本
对于 第一个参数,IE 照样支持"text"和"URL",而 Safari 和 Chrome 仍然只支持 MIME 类型。但是,与 getData()方法不同的是,Safari和 Chrome的 setData()方法不能识别"text"类型。这两个浏览器在 成功将文本放到剪贴板中后,都会返回 true;否则,返回 false
自动切换焦点
tabForward()通过比较用户输入的值与文本框的 maxlength 特性,可以确定是否已经达到大长度。如果这两个值相等(因为浏览器终 会强制它们相等,因此用户绝不会多输入字符),则需要查找表单字段集合,直至找到下一个文本框
把这个函数指定为每个文本框的 onkeyup 事件处理程序,而且keyup 事件会在用户输入了新字符之后触发
HTML5约束验证API
要在 HTML 标记中为特定的字段 指定一些约束,然后浏览器才会自动执行表单验证
必填字段
表单字段中指定了 required 属性
<input type="text" name="username" required>
任何标注有 required 的字段,在提交表单时都不能空着。这个属性适用于<input>、<textarea> 和<select>字段(Opera 11及之前版本还不支持<select>的 required 属性)。在 JavaScript中,通过 对应的 required 属性,可以检查某个表单字段是否为必填字段
var isUsernameRequired = document.forms[0].elements["username"].required;
测试浏览器是否支持 required 属性:
var isRequiredSupported = "required" in document.createElement("input");
其他输入类型
HTML5为元素的 type 属性增加了几个值
"email"和"url"是两个得到支持多的类型,各浏览器也 都为它们增加了定制的验证机制
<input type="email" name ="email">
<input type="url" name="homepage">
存在的问题:"-@-"会被当成一个有效的电子邮件地址
数值范围
"number"、"range"、"datetime"、"datetime-local"、"date"、"month"、"week", 还有"time"
对所有这些数值类型的输入元素,可以指定 min 属性(小的可能值)、max 属性(大的可能值) 和 step 属性(从 min 到 max 的两个刻度间的差值
这些属性在 JavaScript中都能通过对应的元素访问(或修改),两个方法:stepUp() 和 stepDown(),都接收一个可选的参数:要在当前值基础上加上或减去的数值
输入模式
HTML5为文本字段新增了 pattern 属性。这个属性的值是一个正则表达式,用于匹配文本框中的 值
例子:只允许输入数值:<input type="text" pattern="\d+" name="count">
注意,模式的开头和末尾不用加^和$符号(假定已经有了)。这两个符号表示输入的值必须从头到 尾都与模式匹配
与其他输入类型相似,指定 pattern 也不能阻止用户输入无效的文本。这个模式应用给值,浏览 器来判断值是有效,还是无效
在 JavaScript中可以通过 pattern 属性访问模式
var pattern = document.forms[0].elements["count"].pattern;
检测浏览器是否支持 pattern 属性
var isPatternSupported = "pattern" in document.createElement("input");
检测有效性
使用 checkValidity()方法可以检测表单中的某个字段是否有效,若字段的值有效,这个方法返回 true,否则返回 false
要检测整个表单是否有效,可以在表单自身调用 checkValidity()方法。如果所有表单字段都有 效,这个方法返回 true;即使有一个字段无效,这个方法也会返回 false
得到更加具体的信息,使用validity属性来检测表单的有效性
禁用验证
通过设置 novalidate 属性,可以告诉表单不进行验证
在 JavaScript中使用 noValidate 属性可以取得或设置这个值,如果这个属性存在,值为 true, 如果不存在,值为 false
document.forms[0].noValidate = true; //禁用验证
如果一个表单中有多个提交按钮,为了指定点击某个提交按钮不必验证表单,可以在相应的按钮上 添加 formnovalidate 属性
使用 JavaScript也可以设置这个属性
document.forms[0].elements["btnNoValidate"].formNoValidate = true;
选择框脚本
选择框是通过<select>和<option>元素创建的
属性与方法
在 DOM 中,每个<option>元素都有一个 HTMLOptionElement 对象表示
HTMLOptionElement 对象属性
不推荐使用标准 DOM技术 修改<option>元素的文本或者值
注意:选择框的 change 事件与其他表单字段的 change 事件触发的 条件不一样。其他表单字段的 change 事件是在值被修改且焦点离开当前字段时触发,而选择框的 change 事件只要选中了选项就会触发
不同浏览器下,选项的 value 属性返回什么值也存在差别。但是,在所有浏览 器中,value 属性始终等于 value 特性。在未指定 value 特性的情况下,IE8会返 回空字符串,而 IE9+、Safari、Firefox、Chrome和 Opera则会返回与 text 特性相同 的值。
选择选项
只允许选择一项的选择框,访问选中项
选择框的selectedIndex属性
例子:var selectedOption = selectbox.options[selectbox.selectedIndex];
与selectedIndex 不同,在允许多选的选择框中设置选项的 selected 属性,不会取消对其他选中项 的选择,因而可以动态选中任意多个项。但是,如果是在单选选择框中,修改某个选项的 selected 属性则 会取消对其他选项的选择。需要注意的是,将 selected 属性设置为 false 对单选选择框没有影响;selected 属性的作用主要是确定用户选择了选择框中的哪一项
添加选项
使用DOM方法
使用 Option 构造函数来创建新选项
Option 构造函数接受两个参数:文本(text)和值(value);第二个参数可选。 虽然这个构造函数会创建一个 Object 的实例,但兼容 DOM的浏览器会返回一个<option>元素
使用选择框的 add()方法
DOM规定这个方法接受两个参数:要添加 的新选项和将位于新选项之后的选项
移除选项
使用 DOM 的 removeChild()方法, 为其传入要移除的选项
selectbox.removeChild(selectbox.options[0]); //移除第一个选项
使用选择框的 remove()方法。这个方法接受一个参数,即要移除选项的索引
selectbox.remove(0); //移除第一个选项
将相应选项设置为 null
selectbox.options[0] = null; //移除第一个选项
移动和重排选项
移动:使用 DOM 的 appendChild()方法,可以将第一个选择框中的选项直接移动到第二个选择框中
为 appendChild()方法传入一个文档中已有的元素,那么就会先从该元素的 父节点中移除它,再把它添加到指定的位置
移动选项与移除选项有一个共同之处,即会重置每一个选项的 index 属性
重排:将选择框中的某一项移动到特定位置,合适的 DOM 方法就是 insertBefore();appendChild()方法只适用于将选项添加 到选择框的后
IE7存在使用DOM方法重排的选项不能马上正确显示的页面重绘问题
表单序列化
在 JavaScript中,可 以利用表单字段的 type 属性,连同 name 和 value 属性一起实现对表单的序列化
实现表单序列化代码
富文本编辑
又称为 WYSIWYG(What You See Is What You Get,所见即所得)
本质:在页面中嵌入一个包含空 HTML页面的 iframe。通过设置 designMode 属性,这个空白 的 HTML页面可以被编辑,而编辑对象则是该页面元素的 HTML代码
designMode 属性有两 个可能的值:"off"(默认值)和"on"。在设置为"on"时,整个文档都会变得可以编辑(显示插入符 号),然后就可以像使用字处理软件一样,通过键盘将文本内容加粗、变成斜体,等等
contenteditable属性
把 contenteditable 属性应用给页面中的任何元素,然后用户立即就可以编辑该元素
该属性不需要iframe、空白页、JavaScript
contenteditable 属性有三个可能的值:"true"表示打开、"false"表示关闭,"inherit"表示 从父元素那里继承(因为可以在 contenteditable 元素中创建或删除元素)
操作富文本
交互的主要方式使用 document.execCommand()
为 document.execCommand()方法传递 3个参数: 要执行的命令名称、表示浏览器是否应该为当前命令提供用户界面的一个布尔值和执行命令必须的一个值(如果不需要值,则传递 null)
确保跨浏览器的兼容性,第二个参数应该始终设置为 false
不同的浏览器会产生一些不同
执行 bold 命令时,IE和 Opera会使用标签包围文本,Safari和 Chrome使用标签,而 Firefox则使用标签
与命令相关的一些方法
queryCommandEnabled()
可以用它来检 测是否可以针对当前选择的文本,或者当前插入字符所在位置执行某个命令
接收一个参数,即要 检测的命令
如果当前编辑区域允许执行传入的命令,这个方法返回 true,否则返回 false
queryCommandState()
用于确定是否已将指定命令应用到了选择的文本
queryCommandValue()
用于取得执行命令时传入的值
富文本选区
使用框架(iframe)的 getSelection()方法,可以确定实际选择的文本。 这个方法是 window 对象和 document 对象的属性,调用它会返回一个表示当前选择文本的 Selection 对象
Selection对象的属性
对象的方法
表单与富文本
由于富文本编辑是使用 iframe 而非表单控件实现的,因此从技术上说,富文本编辑器并不属于表 单
不会自动提交给服务器,需要我们手动进行提交,可以添加一个隐藏的表单字段,让它的值等于从 iframe 中提取出的 HTML
通过 表单的 onsubmit 事件处理程序实现从 iframe 中提取出 HTML,并将其插入到隐藏的字段中
对于 contenteditable 元素也可以执行类似的操作