《JavaScript高级程序设计》笔记:表单脚本(十四)
表单的基础知识
在HTML中,表单是由<form>元素来表示的,而在JS中,表单对应的是HTMLFormElement类型。HTMLFormElement继承了HTMLElement,因而与其它HTML元素具有相同的默认属性。不过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特性。
取得form元素引用的几种方式,方式一:
var form = document.getElementById('form1');
方式二:
通过document.forms可以取得页面中的所有表单。在这个集合中,可以通过索引或者name值来取得特定的表单。
var firstForm = document.forms[0]; //取得页面中的第一个表单
var myForm = document.forms['form1']; //取得页面中名为"form1"的表单
提交与重置表单
阻止表单提交:
var form = document.getElementById('myForm'); //使用13章封装的EventUtil对象
EventUtil.addHandler(form,'submit',function(event){ //取得事件对象
event = EventUtil.getEvent(event); //阻止默认事件(取消表单的提交)
event.preventDefault(event);
})
提交与重置:
var form = document.getElementById('myForm');
//提交表单
form.submit(); //重置表单
form.reset();
表单字段
每个表单都有elements属性,该属性是所有表单中所有元素的集合。
var form = document.getElementById('myForm'); //取得表单中的第一个字段
var field1 = form.elements[0]; //取得名为"textbox1"的字段
var field2 = form.elements['textbox1']; //取得表单中包含的字段的数量
var fieldCount = form.elements.length;
如果有多个表单控件都在使用同一个name(比如单选按钮),那么就会返回以该name命名的一个nodeList。
表单字段共有的属性和方法:
- disabled:布尔值,表示当前字段是否被禁用。
- form:指向当前字段所属表单的指针;只读。
- name:当前字段的名称。
- readOnly:布尔值,表示当前字段是否只读。
- tabIndex:表示当前字段的切换(tab)序号。
- type:当前字段的类型,如“checkbox”、“radio”等。
- value:当前字段被提交到服务器的值。
除了form属性之外,可以通过JS动态修改其它任何属性。
var form = document.getElementById('myForm');
var field = form.elements[0]; //修改value属性
field.value = "Another value"; //检查form属性的值
console.log(field.form == form); //把焦点设置到当前字段
field.focus(); //禁用当前字段
field.disabled = true; //修改type属性(不推荐,但对<input>来说是可行的)
field.type ="checkbox";
避免多次提交表单,在第一次点击提交表单后,设置提交按钮disabled为true,如下代码:
var form = document.getElementById('myForm'); //避免多次提交表单
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()。例如,在页面加载完成后,把焦点转移到表单中的第一个字段,如下代码:
EventUtil.addHandler(window,"load",function(event){
document.forms[0].elements[0].focus();
})
注意,如果第一个表单字段是<input>元素,且它的type特性的值为“hidden”,那么以上代码会发生错误(高版本浏览器升级修复了该问题)。
HTML5为表单字段新增加了一个autofocus属性。
<input type="text" autofocus/>
检测浏览器是否支持该属性:
EventUtil.addHandler(window,"load",function(event){
var element = document.forms[0].elements[0];
if(element.autofocus !== true){
element.focus();
console.log("JS focus");
}
})
所有表单都支持focus(),change(),blur()这三个事件。如下例子:
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.background != 'red'){
target.style.background = 'yellow';
}
});
EventUtil.addHandler(textbox,"blur",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if(/[^\d]/.test(target.value)){
target.style.background = 'red';
}else{
target.style.background = '';
}
});
EventUtil.addHandler(textbox,"change",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
console.log(target.value)
if(/[^\d]/.test(target.value)){
target.style.background = 'red';
}else{
target.style.background = '';
}
})
文本框脚本
两种方式表示文本框:<input>和<textarea>。
<input>文本框,通过设置size属性,可以指定文本框中显示的字符数。通过设置value特性,可以设置文本框默认的初始值。而maxLength用于指定文本框可以接受的最大字符数。
<input type="text" size="20" value="init value" maxlength="50"/>
对于<textarea>多行文本框而言,要指定文本框的大小,通过设置rows(指定文本框的字符行数)和cols(指定文本框的字符列数)。<textarea>的初始值必须放在<textarea>与</textarea>之间。
<textarea rows="25" cols="5"> init vaule</textarea>
选择文本
上述两种文本框都支持select()方法,这个方法用于选择文本框中的所有文本。
var textbox = document.forms[0].elements["textbox"];
textbox.select();
文本框获得焦点,选择其中所有文本,代码如下:
var textbox = document.forms[0].elements["textbox"];
EventUtil.addHandler(textbox,"focus",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
})
1.选择(select)事件
与select()方法对应的是一个select事件。在选择了文本框的文本时,就会触发select事件。不过到底什么时候触发select事件,还会因浏览器而异。在IE9以及其它高版本浏览器中,当用户选择了文本(而且要释放鼠标),才会触发select事件。而在IE8以及更早的版本中,只要用户选择了一个字母(不必释放鼠标),就会触发select事件。另外,在调用select()方法时也会触发select事件。如下代码:
var textbox = document.forms[0].elements["textbox"];
EventUtil.addHandler(textbox,"select",function(event){
console.log("Text selected:" + textbox.value);
})
2.取得选择的文本
虽然select事件知道用户什么时候选择了文本,但是不知道用户选择了什么文本。HTML5规范为此添加了两个属性:selectionStart和selectionEnd。这两个属性保存的是基于0的数值,表示所选择文本的范围(即文本选区开头和结尾的偏移量)。
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd);
}
var textbox = document.forms[0].elements["textbox"];
EventUtil.addHandler(textbox,"select",function(event){
console.log("Text selected:" + getSelectedText(textbox));
})
IE8及之前的版本不支持这两个属性,有一个document.selection对象,其中保存着用户在整个文档范围内选择的文本信息;也就是说,无法确认用户选择的是页面中哪个部位的文本。不过在和select事件一起使用的时候,可以假定是用户选择了文本框中的文本,因而触发了该事件。要取得选中的文本,首先必须创建一个范围,然后将文本从其中提取出来。代码如下:
function getSelectedText(textbox){
if(typeof textbox.selectionStart == 'number'){
return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd);
}else if(document.selection){
document.selection.createRange().text;
}
}
3.选择部分文本
HTML5也为选择文本框中的部分文本提供了解决方案,即setSelectionRange(),这个方法接受两个参数:要选择第一个字符的索引和要选择最后一个字符之后的字符索引(类似与substring的两个参数),如下例子:
textbox.value = "Hello world!";
//选择所有文本
textbox.setSelectionRange(0,textbox.value.length); //Hello world! //选择前3个字符
textbox.setSelectionRange(0,3); //Hel //选择第4到第6个字符
textbox.setSelectionRange(4,7); //o w textbox.focus();
要看到选中的文本,必须在调用setSelectionRange()之前或之后立即将焦点设置到文本框。IE9以及其它高版本支持这种方案。
IE8以及更早版本支持使用范围选择部分文本。要选择文本框中的部分文本,必须首先使用IE在所有文本框上提供的createTextRange()方法创建一个范围,并将其放到恰当的位置上。然后再使用moveStart()和moveEnd()这两个范围方法将范围移动到位。不过,在调用这两个方法之前,还必须使用collapse()将范围折叠到文本框的开始位置。此时,moveStart()将范围的起点和终点移动到了相同的位置,只要再给moveEnd()传入要选择的字符总数即可。最后一步,就是使用范围的select()方法选择文本。代码如下:
textbox.value = "Hello world!"; var range = textbox.createTextRange(); //选择所有文本
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",textbox.value.length);//Hello world!
range.select(); //选择前3个字符
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",3);//hel
range.select(); //选择第4到第6个字符
range.collapse(true);
range.moveStart("character",4);
range.moveEnd("character",3);//hel
range.select();
跨浏览器:
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();
}
过滤输入
1.屏蔽字符
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))){
EventUtil.preventDefault(event);
}
})
虽然理论上只有在用户按下字符键时才会触发keypress事件,但有些浏览器也会对其它键触发此事件。Firefox和Safari(3.1版本以前)会对向上键、向下键、退格键和删除键触发keypress事件。这就意味着,仅考虑到屏蔽不是数值的字符还是不够,还要避免屏蔽这些极为常见和必要的键。在Firefox中,所有由非字符键触发的keypress事件对应的字符编码为0,而在Safari3.1以前的版本中,对应的字符编码全部为8。为了让代码更通用,只要不屏蔽那些字符编码小于10的键即可,故上面代码变为如下:
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){
EventUtil.preventDefault(event);
}
})
上面代码可以屏蔽非数值字符,但不屏蔽那些也会触发keypress事件的基本按键。
还有一个问题需要处理:复制、粘贴以及其它操作还要用到ctrl键,最后还有一个检测,以确保用户没有按下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.操作剪贴板
HTML5的6个剪贴板事件。
- beforecopy:在发生复制操作前触发。
- copy:在发生复制操作时触发。
- beforecut:在发生剪切操作前触发。
- cut:在发生剪切操作时触发。
- beforepaste:在发生粘贴操作前触发。
- paste:在发生粘贴操作时触发。
在实际的事件发生前,通过beforecopy、beforecut和beforepaste事件可以在向粘贴板发送数据,或者从剪贴板取得数据之前修改数据。不过,取消这些事件并不会取消对剪贴板的操作,只有取消copy、cut和paste事件,才能阻止相应的操作发生。
要访问剪贴板中的数据,可以使用clipboardData对象;在IE中,这个对象是window对象的属性;而在Firefox、Safari和Chrome中,这个对象是相应的event对象的属性。但是,在Firefox、Safari和Chrome中,只有在处理剪贴板事件期间clipboardData对象才有效,这是为了防止对剪贴板的未授权访问;在IE中,则可以随时访问clipboardData对象。
这个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。为了弥合这些差异,可以向EventUtil对象中添加下列方法:
var EventUtil = { //省略的代码 //得到剪贴板数据
getClipboardData:function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
}, //设置剪贴板数据
setClipboardData:function(event,value){
if(event.clipboardData){
return event.clipboardData.setData("text/plain",value);
}else if(window.clipboardData){
return window.clipboardData.setData("text",value);
}
}
};
在paste事件中,确定剪贴板中的数据是否有效,如果无效,取消默认行为,如下代码,如果不是数字,则取消粘贴:
var textbox = document.forms[0].elements["textbox"];
EventUtil.addHandler(textbox,"paste",function(event){
event = EventUtil.getEvent(event);
var text = EventUtil.getClipboardData(event);
if(!/^\d*$/.test(text)){
EventUtil.preventDefault(event);
}
})
自动切换焦点
html:
<form>
<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"/>
</form>
JS代码:
(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
1.必填字段
在表单字段中添加required属性。
<form>
<input type="text" name="text" id="myText" required/>
<input type="submit" value="提交"/>
</form>
JS检测某个表单字段是否为必填字段:
var isUernameRequired = document.forms[0].elements['username'].required;
使用下面这段代码可以测试浏览器是否支持required属性:
var isRequiredSupported = "required" in document.createElement("input");
2.其他输入类型
HTML5为<input>元素的type值新添了几个值。其中“email”和“url”是两个得到支持最多的类型,如下代码:
<form>
<input type="email" name="email" required/>
<input type="url" name="url" required/>
<input type="submit" value="提交"/>
</form>
检测浏览器是否支持这些新类型,不支持它们的旧版本浏览器会自动将未知的值设置为“text”,而支持的浏览器会返回正确的值。例如:
var input = document.createElement("input");
input.type ="email"; var isEmailSupported = (input.type == "email");
3.数值范围
number、range、datetime、datetime-local、date、month、week、time。
对于这些数值类型的输入元素,可以指定min属性(最小的可能值)、max属性(最大的可能值)和step属性(从min到max的两个刻度之间的差值)。
例如,想用户输入0到100的值,并且只能是5的倍数,代码如下:
<input type="number" min="0" max="100" step="5" name="acount"/>
还有两个方法stepUp()和stepDown(),还没有任何浏览器支持,使用如下:
input.stepUp();//加1
input.stepUp(6);//加6
input.stepDown();//减1
input.stepDown(6);//减6
4.输入模式
HTML5为文本字段新增了pattern属性。这个属性的值是一个正则表达式,用于匹配文本框中的值。如下,只运行文本输入数字,代码如下:
<input type="number" pattern="\d+" name="acount"/>
注意,模式的开头和结尾不用加^和$符号。
检测浏览器是否支持pattern属性:
var isPatternSupported = "pattern" in document.createElement("input");
5.检测有效性
使用checkValidity()方法可以检测整个表单,也可以检测某个表单字段。
//检测具体的某个表单字段
if(document.forms[0].elements[0].checkValidity()){
alert("有效的值");
}else{
alert("无效的值");
} //检测整个表单
if(document.forms[0].checkValidity()){
alert("表单有效");
}else{
alert("表单无效");
}
6.禁用验证
通过设置novalidate属性,告诉表单不进行验证。
<form method="post" action="signup.php" novalidate>
<!--这里插入表单元素-->
</form>
在JS中使用noValidate属性可以取得或设置这个值,如果这个属性存在,值为true,不存在则为false。
document.forms[0].noValidate = true; //禁用验证
如果一个表单中有多个提交按钮,可以指定某个提交按钮不必验证表单,可以在相应的按钮上添加formnovalidate属性。
<form method="post" action="foo.php">
<!--这里插入表单元素-->
<input type="submit" value="Regular Submit"/>
<input type="submit" formnovalidate name="btnNovalidate" value="Non-validating Submit"/>
</form>
使用JS设置这个属性:
document.forms[0].elements['btnNovalidate'].formNoValidate = true; //禁用验证
选择框脚本
选择框是通过<select>和<option>元素创建的。除了所有表单字段共有的属性和方法外,HTMLSelectElement类型还提供了下列属性和方法。
- add(newOption,relOption):向控件中插入新<option>元素,其位置在相关项(relOption)之前。
- multiple:布尔值,表示是否允许多项选择;等价于HTML中的multiple特性。
- options:控件中所有<option>元素的HTMLCollection。
- remove(index):移除给定位置的选项。
- selectedIndex:基于0的选中项的索引,如果没有选中项,则值为-1。对于支持多选的控件,只保存选中项中第一项的索引。
- size:选择框中可见的行数;等价于HTML中的size特性。
选择框的type属性不是“select-one”,就是“select-multiple”。这取决于HTML代码中有没有multiple特性。
在DOM中,每个<option>元素都有一个HTMLOptionElement对象。为便于访问数据,HTMLOptionElement对象添加了下列属性:
- index:当前选项在options集合中的索引。
- label:当前选项的标签;等价于HTML中的label特性。
- selected:布尔值,表示当前选项是否被选中。将这个属性设置为true可以选中当前选项。
- text:选项的文本。
- value:选项的值(等价于HTML中的value特性)。
如下代码,HTML:
<form>
<select name="location">
<option value="1">北京</option>
<option value="2">天津</option>
<option value="3">上海</option>
</select>
</form>
JS代码:
var selectbox = document.forms[0].elements['location'];
var text = selectbox.options[0].text; //选项的文本
var value = selectbox.options[0].value;//选项的值
选择选项
使用选择框的selectedIndex属性。如上面代码默认选中了天津。
var selectbox = document.forms[0].elements['location'];
var selectOption = selectbox.options[selectbox.selectedIndex];
选中选择框的第一项:
selectbox.options[0].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.forms[0].elements['location'];
getSelectedOptions(selectbox);
添加选项
第一种,DOM方式添加:
var selectbox = document.forms[0].elements['location'];
var newoption = document.createElement('option');
newoption.appendChild(document.createTextNode('Option text'));
newoption.setAttribute('value',"option value");
selectbox.appendChild(newoption);
第二种方式,使用Option构造函数,Option构造函数接受两个参数:文本(text)和值(value),第二个参数可选。虽然这个构造函数会创建一个Option实例,但兼容DOM的浏览器会返回一个<option>元素。如下代码:
var selectbox = document.forms[0].elements['location'];
var newoption = new Option("Option text","option value");
selectbox.appendChild(newoption); //在IE8以及之前版本有问题
第三种方式使用选择框的add()方法。该方法接受两个参数:要添加的新选项和将位于新选项之后的选项。
var selectbox = document.forms[0].elements['location'];
var newoption = new Option("Option text","option value");
selectbox.add(newoption,undefined);
移除选项
三种方式如下:
var selectbox = document.forms[0].elements['location']; //removeChild()传入要移除的选项
selectbox.removeChild(selectbox.options[0]); //移除第一个选项 //remove(index)传入移除项的索引
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('location1');
var selectbox2 = document.getElementById('location2');
selectbox2.appendChild(selectbox1.options[0]);
移动选项和移除选项有一个共同之处,即会重置每一个选项的index属性。
要将选择框中的某一项移动到特定的位置,最适合的DOM方法insertBefore()。
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]);
表单序列化
在编写代码之前,有必须先搞清楚在表单提交期间,浏览器是怎样将数据发送给服务器的。
- 对表单字段的名称和值进行URL编码,使用和号(&)分隔。
- 不发送禁用的表单字段。
- 只发送勾选的复选框和单选按钮。
- 不发送type为“reset”和“button”的按钮。
- 多选选择框的每个选中的值单独一个条目。
- 在单击提交按钮提交表单的情况下,也会发送提交按钮;否则,不发送提交按钮。也包括type为“image”的<input>元素。
- <select>元素的值,就是选中的<option>元素的value特性的值。如果<option>元素没有value特性,则是<option>元素的文本值。
表单序列化代码:
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[i];
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('&');
}
富文本编辑
富文本编辑,这一技术的本质,就是在页面中嵌入一个包含空HTML页面的iframe。通过设置designMode属性,这个空白的HTML页面可以被编辑,而编辑对象则是该页面<body>元素的HTML代码。designMode属性有两个可能的值:“off”(默认值)和“on”。在设置为“on”时,整个文档都会变得可以编辑(显示插入符号),然后就可以像使用字处理软件一样,通过键盘将文本内容加粗、变成斜线等等。
<iframe name="richedit" style="width:100px;height:100px;" src="index2.html"></iframe>
<script type="text/javascript">
EventUtil.addHandler(window,"load",function(event){
frames["richedit"].document.designMode = "on";
})
</script>
使用contenteditable属性
另一种编辑富文本内容的方式是使用名为contenteditable的特殊属性。这个属性最早由IE实现。使用它,不需要使用iframe、空白页和JS,只要给元素设置该属性即可,如下:
<div class="editable" id="richedit" contenteditable style="width:100px;height:100px;border:1px solid grey"></div>
通过在这个元素上设置contenteditable属性,也能打开或关闭编辑模式,代码如下:
var div = document.getElementById('richedit');
div.contentEditable = "false";
contentEditable属性有三个可能值:“true”表示打开,“false”表示关闭,“inherit”表示从父元素那里继承。
操作富文本
document.execCommand(),这个方法可以对文档执行预定义的命令,这个方法接受三个参数:要执行的命令名称、表示浏览器是否应该为当前命令提供用户界面的一个布尔值(跨浏览器兼容性,一般都设置为false)和执行命令必须的一个值。
使用命令来修改富文本区域的外观,如下例子:
//转换粗体文本
frames["richedit"].document.execCommand("bold",false,null); //转换斜体文本
frames["richedit"].document.execCommand("italic",false,null);
同样的方法适用于页面中contenteditable属性为true的区块:
//转换粗体文本
document.execCommand("bold",false,null); //转换斜体文本
document.execCommand("italic",false,null);
富文本选区
表单与富文本
EventUtil对象方法:
var EventUtil = { //事件处理程序
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent("on" + type,handler);
}else{
element["on" + type] = handler;
}
}, //得到event对象
getEvent:function(event){
return event ? event : window.event;
}, //得到事件目标
getTarget:function(event){
return event.target || event.srcElement;
}, //得到相关元素信息
getRelatedTarget:function(event){
if(event.relatedTarget){
return event.relatedTarget;
}
else if(event.toElement){
return event.toElement;
}
else if(event.fromElement){
return event.fromElement;
}else{
return null;
}
}, //取消默认行为
preventDefault:function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
}, //得到button属性
getButton:function(event){
if(document.implementation.hasFeature("MouseEvents","2.0")){
return event.button;
}else{
switch(event.button){
case 0:
case 1:
case 3:
case 5:
case 7:
return 0;
case 2:
case 6:
return 2;
case 4:
return 1;
}
}
}, //取得鼠标滚轮增量值(delta)
getWheelDelta:function(event){
if(event.wheelDelta){
return event.wheelDelta;
}else{
return -event.detail * 40;
}
}, //字符编码
getCharCode:function(event){
if(typeof event.charCode == 'number'){
return event.charCode;
}else{
return event.keyCode;
}
}, //移除事件处理程序
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);
}else if(element.detachEvent){
element.detachEvent("on" + type,handler);
}else{
element["on" + type] = null;
}
}, //阻止事件捕获或冒泡
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}, //得到剪贴板数据
getClipboardData:function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
}, //设置剪贴板数据
setClipboardData:function(event,value){
if(event.clipboardData){
return event.clipboardData.setData("text/plain",value);
}else if(window.clipboardData){
return window.clipboardData.setData("text",value);
}
}
};
《JavaScript高级程序设计》笔记:表单脚本(十四)的更多相关文章
- JavaScript高级程序设计之表单基础
A FORM <form id='form' action='http://a-response-url' method="post"> <!--maxlengt ...
- 《JAVASCRIPT高级程序设计》表单基础知识和文本框脚本
在HTML中,表单是由<form>元素来表示,在javascript中,表单对应的是HTMLFormElement类型,它具有一些独有的属性和方法: 一.表单基础知识 1.取得表单的方式 ...
- js高级程序设计 笔记 --- 表单
一,基础知识 在html中,表单是form元素,而在js中,表单对应的是HTMLFormElement类型,继承自HTMLElement,其独特的属性和方法有(常见): action:接收请求的URL ...
- JavaScript高级程序设计学习笔记--表单脚本
提交表单 用户单击提交按钮或图像按钮时,就会提交表单.使用<input>和<button>都可以定义提交按钮,只要将其type特性的值设置为"submit" ...
- 《JAVASCRIPT高级程序设计》选择框脚本和富文本编辑
一.选择框脚本 选择框也是表单的一个字段,是通过<select>和<option>元素来创建的,需要使用javascript来控制.选择框拥有以下的属性和方法: 以下介绍一些选 ...
- javaScript高级程序设计笔记 1
核心 ECMAScript 文档对象模型 DOM 浏览器对象模型 BOM 延迟脚本 defer typeof操作符 判断字符类型 返回 undefined boolean s ...
- JavaScript高级程序设计笔记(一)
---恢复内容开始--- 前三章为基础知识,为了方便以后查看,所以比较啰嗦.这里对函数的基本操作没有记录. 1.JavaScript的实现 虽然 JavaScript 和 ECMAScript 通常都 ...
- JavaScript高级程序设计笔记之面向对象
说起面向对象,大部分程序员首先会想到 类 .通过类可以创建许多具有共同属性以及方法的实例或者说对象.但是JavaScript并没有类的概念,而且在JavaScript中几乎一切皆对象,问题来了,Jav ...
- javascript高级程序设计--笔记01
概述 JavaScript的实现包含三个部分: 1 核心(ECMAScript) 提供核心语言功能 2 文档对象模型(DOM) 一套提供了访问以及操作网页内容的API 3 浏览器对象模型( ...
- <javascript高级程序设计>笔记
1.要讲一个值转换成其对应的Boolean类型 ,可以调用转型函数Boolean(). var message=“hello world!”; var messageAsBoolean=Boolean ...
随机推荐
- 机器学习——KMeans聚类,KMeans原理,参数详解
0.聚类 聚类就是对大量的未知标注的数据集,按数据的内在相似性将数据集划分为多个类别,使类别内的数据相似度较大而类别间的数据相似度较小,聚类属于无监督的学习方法. 1.内在相似性的度量 聚类是根据数据 ...
- netcore程序部署到docker
1.基础准备 1. ubuntu 18.04 2. docker version 18.09 3. netcore 2.1 2.简介 自从netcore支持跨平台之后,以及现在很多公司都是采用容器化部 ...
- ASP.NET Core微服务实战系列
希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. 前言 这里记录的是个人奋斗和成长的地方,该篇只是一个系列目录和构想 ...
- spring boot整合mybatis方式一
方式一: 导入maven依赖: <!--web依赖配置--> <dependency> <groupId>org.springframework.boot</ ...
- css公共库——清除浮动
清除浮动是css的基础,但有时候会忘了一些最简单的东西 浮动因为在文档流之外,所以会造成父元素的坍塌.父元素之后的元素排版就会乱. 常用的方法是在浮动父元素中添加cf类,然后定义cf样式,并将其放在公 ...
- Android ADB命令详解
adb的全称为Android Debug Bridge.是android司机经常用到的工具 . 你能在本篇文章中学到什么? adb基本指令 Shell AM&PM adb模拟用户事件 logc ...
- sublime实现markdown浏览器预览
效果预览 实现 首先下载插件OmniMarkupPreviewer 方法:ctrl + shift + P 安装完成后搜索'OmniMarkupPreviewer'双击即可 下载完成后新建.md文件 ...
- Windows Server 2016-图形化新建域用户(一)
上章节我们介绍了有关OU组织单位的日常管理,本章我们将对域用户的创建进行简单介绍,常规的操作方法是通过管理控制台图形化手工创建,具体操作方法如下: 1.常规管理控制台 Active Directory ...
- ZJOI2019二轮游记
Postscript 这个彩笔的省选随心游被中考实验考试坑掉了 所以前两天都一直脱离部队,第一天讲课完了才有的过去 一轮凉了那么二轮翻盘?翻车预定.之后还有上海的ACM没有CXR神仙的ACM窝怎么打啊 ...
- 使用 Node.js 搭建 Web 服务器
使用Node.js搭建Web服务器是学习Node.js比较全面的入门教程,因为实现Web服务器需要用到几个比较重要的模块:http模块.文件系统.url解析模块.路径解析模块.以及301重定向技术等, ...