一、表单的基础知识
取得元素引用的方法
- getElementById()
- document.forms可以取得页面中所有的表单集合,HTMLCollection
1.1、提交表单
<input type="submit" value="Submit Form">
<button type="submit">Submit Form</button>
<input type="image" src="./课程安排.png">
阻止表单提交
var form=document.getElementById("myForm");
EventUtil.addHandler(form,"submit",function(event){
event=EventUtil.getEvent(event);
EventUtil.preventDefault(event)
})
另外,使用submit()也可以提交表单,而且,这种方式无需包含提交按钮,任何时候都可以正常提交
为避免多次提交,在一次提交表单后禁用提交按钮或者利用onsubmit事件处理程序取消后续的表单提交,用submit()提交表单时,不会触发submit事件
1.2、重置表单
<input type="reset" value="Submit Form">
<button type="reset">Submit Form</button>
阻止重置表单
var form=document.getElementById("myForm");
EventUtil.addHandler(form,"reset",function(event){
event=EventUtil.getEvent(event);
EventUtil.preventDefault(event)
})
另外,使用reset()也可以重置表单,但是,它会触发reset事件
1.3、表单字段
每个表单都有elements属性,该属性时表单中所有表单的集合,这个集合是一个有序列表,例如
var form=document.getElementById("myForm");
var colorFields=form.elements["color"];
console.log(colorFields.length)//3
var firstColorField=colorFields[0]
var firstFormField=form.elements[0];
console.log(firstColorField===firstFormField)//true
通过form.elements[0]访问到的第一个表单字段,与包含在form.elements[“color”]中的第一个元素下同
1.3.1、共有表单的字段属性
处理元素之外,所有的表单都拥有相同的一组属性,表单字段的共有属性:
disabled,form,name,readOnly,tabIndex,type,value其中form指向当前字段所属表单的指针,不可以修改,其他属性都可以动态修改
所以在单击一次就禁用的例子中,可以使用
EventUtil.addHandler(form, "submit", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//get the submit button
var btn = target.elements["submit-btn"];
//disable it
btn.disabled = true;
});
不要使用onclick事件处理程序来实现这个功能,原因是不同的浏览器之间存在时差
1.3.2、共有的表单字段
focus():获得焦点
blur():移除焦点
新增一个autofocus属性,不用上述方法就能将焦点移动到相应的字段
为了保证前面的代码在设置autofocus的浏览器中正常运行,必须检测是否设置了这个属性,如果设置了,就不用调用focus()
EventUtil.addHandler(window,"load",function(event){
var element=document.forms[0].elements[1]
if(element.autofocus!==true){
element.focus();
console.log("JS focus")
}
})
1.3.3、共有的表单字段事件
blur,change,focus
其中change事件:对于和元素,在他们失去焦点且value值改变时触发,对于,在其选项改变时触发
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);
var target=EventUtil.getTarget(event);
if(/[^\d]/.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]/.test(target.value)){ t
arget.style.backgroundColor="red"
}else{ t
arget.style.backgroundColor=""
}
})
在此,focus事件处理程序将文本框的背景颜色改为黄色,表明已经激活,blur和change事件处理程序则会发现非数字字符时,将背景改为红色
二、文本框脚本
有一个forms属性和elements属性(表单中的所有字段)
单行文本框
多行文本框
- 在单行文本框中
size:设置文本框能够显示的行数
value:文本框的初始值
maxlegth:指定文本框可以接受的最大字符数 - 在多行文本框中
rows指定字符行数
cols指定字符列数
2.1、选择文本
select():在调用这个方法时,会将焦点设置到文本框中
var form=document.forms[0].elements["textbox"]
form.select()
在调用这个方法时,如果文本框中存在value,会选中所有的文本值,兼容性写法:
var form=document.forms[0].elements["textbox"]EventUtil.addHandler(form, "focus", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
2.1.1、选择(select)事件
与select()方法对应,是一个select事件。在用户选择了文本框中的文本时,就会触发select事件
var form=document.forms[0].elements["textbox"]EventUtil.addHandler(form, "select", function(event){
console.log("Text selected"+form.value)
});
2.2.2、取得选择文本
selectionStart和selectEnd属性,这两个属性中保存的是基于0的数值,表示所选择的文本的范围,IE8更早的版本支持document.selection
function getSelectedText(textbox){
if(typeof textbox.selectionStart=='number'){
return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd)
}else if(document.selection){
return document.selection.createRange().text;
}
}
EventUtil.addHandler(window,"load",function(event){
var form=document.forms[0].elements["textbox"]
EventUtil.addHandler(form,"select",function(event){
console.log(getSelectedText(form))
})
})
2.2.3、选择部分文本
setSelectionRange():接受两个参数,要选择的第一个字符的索引和要选择的最后一个字符之后的字符的索引
form.value="Hello World!";
EventUtil.addHandler(form,"focus",function(event){
form.setSelectionRange(0,6)})
IE浏览器下,需要使用collapse将起点和终点折叠到起点位置,同时还要使用moveStart()和moveEnd()
form.value="Hello World!"var range=form.createTextRange();
range.collapse(true);range.moveStart("character",0);
range.moveEnd("character",form.value.length)r
ange.select()
实现跨浏览器
function selectText(textbox,startIndex,endIndex){
if(textbox.setSelectionRange){ textbox.setSelectionRange(startIndex,endIndex)
}else if(textbox.createTextRange){
var range=textbox.createTextRange()
range.collapse(true)
range.moveStart("chaacter",startIndex)
range.moveEbd("character",endIndex)
range.select()
}
textbox.focus()
}
var textbox=document.forms[0].elements[0]
textbox.value="Hello World!"selectText(textbox,0,3)
2.2、过滤输入
2.2.1、屏蔽字符
var textbox=document.forms[0].elements[0]
EventUtil.addHandler(textbox,"keypress",function(event){
event=EventUtil.getEvent(event);
EventUtil.preventDefault(event)
})
此案例屏蔽了所有键,用户不能输入
要想屏蔽特定的字符,则需要检测keypress事件对应的字符编码
var textbox=document.forms[0].elements[0]
EventUtil.addHandler(textbox,"keypress",function(event){
event=EventUtil.getEvent(event);
var charCode=EventUtil.getCharCode(event)
if(!/\d/.test(String.fromCharCode(charCode))){
EventUtil.preventDefault(event)
}
})
屏蔽了非数字字符
为了保证兼容性,我们将屏蔽的charCode设为小于10,
另外,还要考虑复制粘贴等组合键
EventUtil.addHandler(textbox,"keypress",function(event){
event=EventUtil.getEvent(event);
var charCode=EventUtil.getCharCode(event)
if(!/\d/.test(String.fromCharCode(charCode)) &&charCode>9 &&event.ctrlKey){
EventUtil.preventDefault(event)
}
})
2.2.2、操作剪切板
六个事件
beforecopy,copy,beforecut,cut,beforepaste,paste要访问剪切板中的数据,可以使用clipboardData对象,在IE中,这个对象是window对象属性,在Firefox,Chrome,Safari中,这个对象是event属性
这个对象有三个方法:getData(),setData(),clearDate()
- getData():接受一个参数,IE中为“text”或者“URL”,其他浏览器text/plain,可以用text代替
- setData():接受两个参数,第一个参数为数据类型,IE中为“text”或者“URL”,其他浏览器text/plain,不能用text代替,第二个参数为要放在剪切办中的文本,IE
getClipboardText:function(event){
var clipboardData=(event.clipboardData||window.clipboardData);
return clipboardData.getData("text")
},
setClipboardText:function(event){
if(event.clipboardData){
return event.clipboardData.setData("text/plain",value)
}else if(window.clipboardData){
return window.clipboardData.setData("text",value)
}
}
在需要粘贴到文本框中的文本包含某些字符,或者符合某种格式要求是,能够访问剪切板是非常有效的
EventUtil.addHandler(textbox,"paste",function(event){
event=EventUtil.getEvent(event);
var text=EventUtil.getClipboardText(event)
if(!/^\d*$/.test(text)){
EventUtil.preventDefault(event)
}
})
此案例只能复制数字文本
2.3、自动切换焦点
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;
}
}
}
}
2.4、HTML5约束验证API
2.4.1、必填字段
required
2.4.2、其他输入类型
email和url
2.4.3、数值范围
2.4.4、输入模式
pattern,这个属性的值是一个正则表达式,用于匹配文本框中的值
2.4.5、检测有效性
checkValidity()
2.4.6、禁用设置
novalidate属性
三、选择框脚本
有一个options属性
选择框是通过和元素创建的,有以下属性和方法:
add(newOption,relOption):向控件中插入新的元素,其位置在相关项(relOption)之前
multiple:布尔值,表示是否允许多项选择
options:
remove(index):移除给定位置的选项
selectedIndex:基于0的选中项的索引,如果没有选中项,则为-1
在DOM中,每个元素都有一个HTMLOptionElement对象表示。为了便于访问数据,给这个对象添加了如下的属性
index,label,selected,text,value
var text=selectbox.options[0].text
var value=selectbox.options[0].value
3.1选择选项
- 对于只允许选择一项的选择框,使用selectedIndex属性
ar btn3=document.getElementById("btnSelected"),
textbox=document.getElementById("selLocation");
EventUtil.addHandler(btn3,"click",function(){
var index=textbox.selectedIndex;
var option=textbox.options[index]
console.log(index,option.text,option.value)
})
- 另一种选择选项的方法,就是取得对某一项的引用,然后将其属性设置为true,它与selsectedIndex不同,在允许多选的选择框中设置selected属性,不会取消对其他项的选择,但是如果在单选框中,会取消选择
实际上,selected属性地主要作用是确定用户选择了选择框中地哪一项,下面这个例子用于单选和多选
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 message=''
EventUtil.addHandler(btn3, "click", function(event){
var selectedOptions = getSelectedOptions(selectbox);
var message = "";
for (var i=0, len=selectedOptions.length; i < len; i++){
message+= "Selected index: " + selectedOptions[0].index + "\nSelected text: " + selectedOptions[0].text + "\nSelected value: " + selectedOptions[0].value + "\n\n";
}
console.log(message)
});
3.2、添加选项
- DOM方法
- 使用Option构造函数,接受两个参数:文本(text)和值(value)
var selectbox=document.getElementById("selLocation")
var newOption=new Option("Option text","Option value");
selectbox.appendChild(newOption)
- 使用选择框地add():接受两个参数,要添加地新选项和位于新选项之后的选项,在IE中,第二个参数可选,而且如果指定,该参数必须是新选项之后地索引,DOM中第二个参数必须,所以浏览器要兼容,必须将第二个参数设为undefined
var selectbox=document.getElementById("selLocation")
var newOption=new Option("Option text","Option value");
selectbox.add(newOption,undefined)
`
3.3、移除选项
- DOM
- 选择框的remove():这个方法接受一个参数,要移除地选项地索引
- 将相应地选项设置为null
3.4、移动和重排选项
appendChild()
(function(){
var btn=document.getElementById("btnMove");
EventUtil.addHandler(btn,"click",function(){
var selectbox1 = document.getElementById("selLocations1"),
selectbox2 = document.getElementById("selLocations2"),
textbox = document.getElementById("txtIndex");
selectbox2.appendChild(selectbox1.options[parseInt(textbox.value,10)])
})
})()
insertBefore()
(function(){
var btnUp = document.getElementById("btnUp");
var btnDown = document.getElementById("btnDown"); EventUtil.addHandler(btnUp,"click",function(){
var selectbox=document.getElementById("selLocations"),
textbox=document.getElementById("txtIndex")
var optionToMove=selectbox.options[parseInt(textbox.value,10)];
if(optionToMove.index-1>0){
selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index-1])
}
})
EventUtil.addHandler(btnDown,"click",function(){
var selectbox=document.getElementById("selLocations"),
textbox=document.getElementById("txtIndex")
var optionToMove=selectbox.options[parseInt(textbox.value,10)];
selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index+2])
})
})()
3.5、表单序列化
四、富文本编辑
通过设置designMode属性,可以让空白的HTML页面可以被编辑,其中“on"为可编辑,”off“为不可编辑
<iframe name="richedit" style="height: 100px;width: 100px;"></iframe>
EventUtil.addHandler(window,"load",function(){
frames["richedit"].document.designMode="on"
})
4.1、使用contenteditable属性
可以把该属于给页面中的任何元素
<div class="editable" id="richedit" contenteditable style="width: 100px;height: 100px;"></div>
var div=document.getElementById("richedit");
div.contentEditable="true"
4.2、操作富文本
document.execCommand():这个方法接受三个参数,要执行的命令名称,表示浏览器是否应该为当前命令提供界面的一个布尔值,执行命令必须的一个之(如果不需要,传null),为保证浏览器的兼容性,第二个参数始终设为false
命令名称见书p440
可以在任何时候使用这些命令来修改富文本编辑器的外观
//方法一:设置designMode属性时
EventUtil.addHandler(window,"load",function(){
frames["richedit"].document.designMode="on"
})
var btn1=document.getElementById("btn1")
var btn2=document.getElementById("btn2")
EventUtil.addHandler(btn1,"click",function(){
frames["richedit"].document.execCommand("bold", false, null);
})
EventUtil.addHandler(btn2,"click",function(){
frames["richedit"].document.execCommand("italic", false, null);
//方法二:设置contenteditable属性时
var btn1=document.getElementById("btn1")
var btn2=document.getElementById("btn2")
EentUtil.addHandler(btn1,"click",function(){
document.execCommand("bold",false,null)})
EventUtil.addHandler(btn2,"click",function(){
document.execCommand("italic",false,null)
})
另外,哈有一些与命令祥光的方法:
第一个是queryCommandEnabled(),用来检测是否可以针对当前选择的文本,或者当前插入的字符所在的位置执行某个命令,这个方法接受一个参数,即要检测的命令。如果当前编辑区域允许执行传入的命令,这个方法返回true
EventUtil.addHandler(btn3,"click",function(){
var result= frames["richedit"].document.queryCommandEnabled("bold")
console.log(result)})
第二个方法是queryCommandState()方法用于确定是否已经将指定命令应用到了选择的文本
EventUtil.addHandler(btn3,"click",function(){
var result= frames["richedit"].document.queryCommandState("bold")
console.log(result)})
第三个方法是queryCommandValue用来取得执行命令时传入的值
EventUtil.addHandler(btn3,"click",function(){
var result= frames["richedit"].document.queryCommandValue("bold")
})
4.3、富文本选区
使用框架(iframe)的getSelection()方法,可以确定实际选择的文本,这个方法是window对象的属性,返回它会第哦啊用一个表示当前选择文本的Selection对象
EventUtil.addHandler(btn4,"click",function(){
frames["richedit"].document.execCommand("fontsize", false, 12);
var selection=frames["richedit"].getSelection();
var selectText=selection.toString();
var range=selection.getRangeAt(0)console.log(range)
})
IE浏览器中,要先创建一个范围,在访问其属性
var range = frames["richedit"].document.selection.createRange();
range.pasteHTML("<span style=\"background-color:yellow\">" + range.htmlText + "</span>");
4.4、表单与富文本
由于富文本编辑器使用iframe而非表单控件实现的,因此从技术上来说,富文本编辑器并不属于表单,换句话说,富文本编辑器中的不会被自动提交给服务器,而需要我们手动来提取并提交,为此,通常可以添加一个隐藏的表单字段,让它的值等于从iframe中提取的HTML
EventUtil.addHandler(document.forms[0],"submit",function(event){
event=EventUtil.getEvent(event)
var target=EventUtil.getTarget(event)
target.elements["comments"].value=frames["richedit"].document.body.innerHTML;
})
对于contenteditable元素,也可以执行类似操作
EventUtil.addHandler(document.forms[0],"submit",function(event){
event=EventUtil.getEvent(event)
var target=EventUtil.getTarget(event)
target.elements["comments"].value=document.getElementById("richedit").innerHTML;
})