之外,所有表單字段都有 type 屬性。對于 元素,這個(gè)值等于 HTML 特性 type 的值。對于其他元素,這個(gè) type 屬性的值如下表所列。
1.3.2共有的表單字段方法
每個(gè)表單字段都有兩個(gè)方法: focus() 和 blur() ;
focus() 方法用于將瀏覽器的焦點(diǎn)設(shè)置到表單字段,即激活表單字段,使其可以響應(yīng)鍵盤事件。
HTML5 為表單字段新增了一個(gè) autofocus 屬性。在支持這個(gè)屬性的瀏覽器中,只要設(shè)置這個(gè)屬性,不用 JavaScript 就能自動(dòng)把焦點(diǎn)移動(dòng)到相應(yīng)字段。
blur() 方法,它的作用是從元素中移走焦點(diǎn)。在調(diào)用 blur()方法時(shí),并不會(huì)把焦點(diǎn)轉(zhuǎn)移到某個(gè)特定的元素上;僅僅是將焦點(diǎn)從調(diào)用這個(gè)方法的元素上面移走而已。
1.3.3共有的表單字段事件
除了支持鼠標(biāo)、鍵盤、更改和 HTML 事件之外,所有表單字段都支持下列 3 個(gè)事件。
blur: 當(dāng)前字段失去焦點(diǎn)時(shí)觸發(fā)。
change: 對于 和
focus: 當(dāng)前字段獲得焦點(diǎn)時(shí)觸發(fā)。
2、文本框腳本
在 HTML 中,有兩種方式來表現(xiàn)文本框:一種是使用 元素的單行文本框,另一種是使用
(1)要表現(xiàn)文本框,必須將 元素的 type 特性設(shè)置為"text"。而通過設(shè)置 size 特性,可以指定文本框中能夠顯示的字符數(shù)。通過 value 特性,可以設(shè)置文本框的初始值,而 maxlength 特性則用于指定文本框可以接受的最大字符數(shù)。
//創(chuàng)建一個(gè)文本框,讓它能夠顯示 25 個(gè)字符,但輸入不能超過 50 個(gè)字符
(2)
initial value
2.1 選擇文本
上述兩種文本框都支持 select()方法,這個(gè)方法用于選擇文本框中的所有文本。 在調(diào)用 select() 方法時(shí),大多數(shù)瀏覽器( Opera 除外)都會(huì)將焦點(diǎn)設(shè)置到文本框中。這個(gè)方法不接受參數(shù),可以在任何時(shí)候被調(diào)用。
var textbox = document.forms[0].elements["textbox1"];
textbox.select();
2.1.1 選擇(select)事件
與 select() 方法對應(yīng)的,是一個(gè) select 事件。在選擇了文本框中的文本時(shí),就會(huì)觸發(fā) select事件。另外,在調(diào)用 select()方法時(shí)也會(huì)觸發(fā) select 事件。
var textbox = document.forms[0].elements["textbox1"];
EventUtil.addHandler(textbox, "select", function(event){
var alert("Text selected" + textbox.value);
});
2.1.2 取得選擇的文本
(1)采取的辦法是添加兩個(gè)屬性: selectionStart 和 selectionEnd 。這兩個(gè)屬性中保存的是基于 0 的數(shù)值,表示所選擇文本的范圍(即文本選區(qū)開頭和結(jié)尾的偏移量)。
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
}
因 為 substring() 方 法 基 于 字 符 串 的 偏 移 量 執(zhí) 行 操 作 , 所 以 將 selectionStart 和selectionEnd 直接傳給它就可以取得選中的文本。 (2)IE8 及更早的版本中有一個(gè) document.selection 對象,其中保存著用戶在整個(gè)文檔范圍內(nèi)選擇的文本信息。
//獲取選中的文本
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;
}
}
2.1.3 選擇部分文本
(1)所有文本框都有一個(gè)setSelectionRange()方法 。這個(gè)方法接收兩個(gè)參數(shù):要選擇的第一個(gè)字符的索引和要選擇的最后一個(gè)字符之后的字符的索引(類似于 substring()方法的兩個(gè)參數(shù))?!綢E9、 Firefox、 Safari、 Chrome 和 Opera 】
textbox.value = "Hello world!"
//選擇所有文本
textbox.setSelectionRange(0, textbox.value.length); //"Hello world!"
//選擇前 3 個(gè)字符
textbox.setSelectionRange(0, 3); //"Hel"
//選擇第 4 到第 6 個(gè)字符
textbox.setSelectionRange(4, 7); //"o w"
(2)IE 在所有文本框上提供的 createTextRange()方法創(chuàng)建一個(gè)范圍,并將其放在恰當(dāng)?shù)奈恢蒙?。然后,再使?moveStart()和 moveEnd()這兩個(gè)范圍方法將范圍移動(dòng)到位。不過,在調(diào)用這兩個(gè)方法以前,還必須使用 collapse()將范圍折疊到文本框的開始位置。此時(shí),moveStart()將范圍的起點(diǎn)和終點(diǎn)移動(dòng)到了相同的位置,只要再給 moveEnd()傳入要選擇的字符總數(shù)即可。最后一步,就是使用范圍的 select()方法選擇文本?!綢E8 及更早版本】
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 個(gè)字符
range.collapse(true);
range.moveStart("character", 0);
range.moveEnd("character", 3);
range.select(); //"Hel"
//選擇第 4 到第 6 個(gè)字符
range.collapse(true);
range.moveStart("character", 4);
range.moveEnd("character", 3);
range.select(); //"o w"
(3)跨瀏覽器實(shí)現(xiàn)選擇部分文本,可以將上述兩個(gè)方案組合起來。
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();
}
這個(gè) selectText()函數(shù)接收三個(gè)參數(shù):要操作的文本框、要選擇文本中第一個(gè)字符的索引和要選擇文本中最后一個(gè)字符之后的索引。首先,函數(shù)測試了文本框是否包含 setSelectionRange()方法。如果有,則使用該方法。否則,檢測文本框是否支持 createTextRange()方法。如果支持,則通過創(chuàng)建范圍來實(shí)現(xiàn)選擇。最后一步,就是為文本框設(shè)置焦點(diǎn),以便用戶看到文本框中選擇的文本。可以像下面這樣使用 selectText()方法。
textbox.value = "Hello world!"
//選擇所有文本
selectText(textbox, 0, textbox.value.length); //"Hello world!"
//選擇前 3 個(gè)字符
selectText(textbox, 0, 3); //"Hel"
//選擇第 4 到第 6 個(gè)字符
selectText(textbox, 4, 7); //"o w
2.2 過濾輸入
2.2.1 屏蔽字符
有時(shí)候,我們需要用戶輸入的文本中包含或不包含某些字符。如果只想屏蔽特定的字符,則需要檢測 keypress 事件對應(yīng)的字符編碼,然后再?zèng)Q定如何響應(yīng)。例如,下列代碼只允許用戶輸入數(shù)值。
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.2.2 操作剪切板
下列就是 6 個(gè)剪貼板事件:
beforecopy :在發(fā)生復(fù)制操作前觸發(fā)。
copy :在發(fā)生復(fù)制操作時(shí)觸發(fā)。
beforecut :在發(fā)生剪切操作前觸發(fā)。
cut :在發(fā)生剪切操作時(shí)觸發(fā)。
beforepaste :在發(fā)生粘貼操作前觸發(fā)。
paste :在發(fā)生粘貼操作時(shí)觸發(fā)。
要訪問剪貼板中的數(shù)據(jù),可以使用 clipboardData 對象。這個(gè) clipboardData 對象有三個(gè)方法: getData() 、 setData() 和clearData() 。 其中, getData()用于從剪貼板中取得數(shù)據(jù),它接受一個(gè)參數(shù),即要取得的數(shù)據(jù)的格式;setData()方法的第一個(gè)參數(shù)也是數(shù)據(jù)類型,第二個(gè)參數(shù)是要放在剪貼板中的文本。
var EventUtil = {
//從剪貼板中取得數(shù)據(jù)
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);
}
},
}
2.3 自動(dòng)切換焦點(diǎn)
使用 JavaScript 可以從多個(gè)方面增強(qiáng)表單字段的易用性。其中,最常見的一種方式就是在用戶填寫完當(dāng)前字段時(shí),自動(dòng)將焦點(diǎn)切換到下一個(gè)字段。這種“自動(dòng)切換焦點(diǎn)”的功能,可以通過下列代碼實(shí)現(xiàn):
(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);
})();
開始的 tabForward()函數(shù)是實(shí)現(xiàn)“自動(dòng)切換焦點(diǎn)”的關(guān)鍵所在。這個(gè)函數(shù)通過比較用戶輸入的值與文本框的 maxlength 特性,可以確定是否已經(jīng)達(dá)到最大長度。如果這兩個(gè)值相等(因?yàn)闉g覽器最終會(huì)強(qiáng)制它們相等,因此用戶絕不會(huì)多輸入字符),則需要查找表單字段集合,直至找到下一個(gè)文本框。找到下一個(gè)文本框之后,則將焦點(diǎn)切換到該文本框。然后, 我們把這個(gè)函數(shù)指定為每個(gè)文本框的 onkeyup事件處理程序。由于 keyup 事件會(huì)在用戶輸入了新字符之后觸發(fā),所以此時(shí)是檢測文本框中內(nèi)容長度的最佳時(shí)機(jī)。這樣一來,用戶在填寫這個(gè)簡單的表單時(shí),就不必再通過按制表鍵切換表單字段和提交表單了。
2.4 HTML5約束驗(yàn)證API
2.4.1 必填字段
(1)第一種情況是在表單字段中指定了 required 屬性
(2)在 JavaScript 中,通過對應(yīng)的 required 屬性,可以檢查某個(gè)表單字段是否為必填字段。
var isUsernameRequired = document.forms[0].elements["username"].required;
//使用下面這行代碼可以測試瀏覽器是否支持 required 屬性。
var isRequiredSupported = "required" in document.createElement("input");
2.4.2 其他輸入類型
(1)HTML5 為 元素的 type 屬性又增加了幾個(gè)值。這些新的類型不僅能反映數(shù)據(jù)類型的信息,而且還能提供一些默認(rèn)的驗(yàn)證功能。其中, "email" 和"url" 是兩個(gè)得到支持最多的類型.
(2)要檢測瀏覽器是否支持這些新類型,可以在 JavaScript 創(chuàng)建一個(gè) 元素,然后將 type 屬性設(shè)置為"email"或"url",最后再檢測這個(gè)屬性的值。不支持它們的舊版本瀏覽器會(huì)自動(dòng)將未知的值設(shè)置為"text",而支持的瀏覽器則會(huì)返回正確的值。
var input = document.createElement("input");
input.type = "email";
var isEmailSupported = (input.type == "email");
2.4.3 數(shù)值范圍
HTML5 還定義了另外幾個(gè)輸入元素。這幾個(gè)元素都要求填寫某種基于數(shù)字的值: "number"、 "range"、 "datetime"、 "datetime-local"、 "date"、 "month"、 "week",還有"time"。
對所有這些數(shù)值類型的輸入元素,可以指定 min 屬性 (最小的可能值)、 max 屬性 (最大的可能值)和 step 屬性 (從 min 到 max 的兩個(gè)刻度間的差值)。
//讓用戶只能輸入 0 到 100 的值,而且這個(gè)值必須是 5 的倍數(shù)
以上這些屬性在 JavaScript 中都能通過對應(yīng)的元素訪問(或修改)。此外,還有兩個(gè)方法: stepUp() 和 stepDown() ,都接收一個(gè)可選的參數(shù):要在當(dāng)前值基礎(chǔ)上加上或減去的數(shù)值。
input.stepUp(); //加 1
input.stepUp(5); //加 5
input.stepDown(); //減 1
input.stepDown(10); //減 10
2.4.4 輸入模式
HTML5 為文本字段新增了 pattern 屬性 。這個(gè)屬性的值是一個(gè)正則表達(dá)式,用于匹配文本框中的值。
//如果只想允許在文本字段中輸入數(shù)值,可以像下面的代碼一樣應(yīng)用約束:
//在 JavaScript 中可以通過 pattern 屬性訪問模式。
var pattern = document.forms[0].elements["count"].pattern;
//使用以下代碼可以檢測瀏覽器是否支持 pattern 屬性。
var isPatternSupported = "pattern" in document.createElement("input");
2.4.5 檢測有效性
使用 checkValidity()方法 可以檢測表單中的某個(gè)字段是否有效。所有表單字段都有個(gè)方法,如果字段的值有效,這個(gè)方法返回 true,否則返回 false。
if (document.forms[0].elements[0].checkValidity()){
//字段有效,繼續(xù)
} else {
//字段無效
}
與 checkValidity()方法簡單地告訴你字段是否有效相比, validity 屬性 則會(huì)告訴你為什么字段有效或無效。這個(gè)對象中包含一系列屬性,每個(gè)屬性會(huì)返回一個(gè)布爾值。
customError :如果設(shè)置了 setCustomValidity(),則為 true,否則返回false。
patternMismatch:如果值與指定的pattern 屬性不匹配,返回true。
rangeOverflow:如果值比 max 值大,返回 true。
rangeUnderflow:如果值比 min 值小,返回true。
stepMisMatch:如果 min 和 max 之間的步長值不合理,返回true。
tooLong:如果值的長度超過了maxlength 屬性指定的長度,返回true。有的瀏覽器(如Firefox 4)會(huì)自動(dòng)約束字符數(shù)量,因此這個(gè)值可能永遠(yuǎn)都返回false。
typeMismatch:如果值不是"mail"或"url"要求的格式,返回true。
valid:如果這里的其他屬性都是false,返回 true。 checkValidity()也要求相同的值。
valueMissing:如果標(biāo)注為 required 的字段中沒有值,返回true。
2.4.6 禁用驗(yàn)證
通過設(shè)置 novalidate 屬性,可以告訴表單不進(jìn)行驗(yàn)證。
//在 JavaScript 中使用 noValidate 屬性可以取得或設(shè)置這個(gè)值,如果這個(gè)屬性存在,值為 true,如果不存在,值為 false。
document.forms[0].noValidate = true; //禁用驗(yàn)證
如果一個(gè)表單中有多個(gè)提交按鈕,為了指定點(diǎn)擊某個(gè)提交按鈕不必驗(yàn)證表單,可以在相應(yīng)的按鈕上添加 formnovalidate 屬性。
//使用 JavaScript 也可以設(shè)置這個(gè)屬性。
//禁用驗(yàn)證
document.forms[0].elements["btnNoValidate"].formNoValidate = true;
3、選擇框腳本
選擇框是通過和元素創(chuàng)建的。為了方便與這個(gè)控件交互,除了所有表單字段共有的屬性和方法外, HTMLSelectElement 類型還提供了下列屬性和方法。
add(newOption, relOption):向控件中插入新元素,其位置在相關(guān)項(xiàng)( relOption)之前。
multiple:布爾值,表示是否允許多項(xiàng)選擇;等價(jià)于 HTML 中的 multiple 特性。
options:控件中所有元素的 HTMLCollection。
remove(index):移除給定位置的選項(xiàng)。
selectedIndex:基于 0 的選中項(xiàng)的索引,如果沒有選中項(xiàng),則值為-1。對于支持多選的控件,只保存選中項(xiàng)中第一項(xiàng)的索引。
size:選擇框中可見的行數(shù);等價(jià)于 HTML 中的 size 特性;
選擇框的 type 屬性不是"select-one",就是"select-multiple",這取決于 HTML 代碼中有沒有 multiple 特性。選擇框的 value 屬性由當(dāng)前選中項(xiàng)決定,相應(yīng)規(guī)則如下。
如果沒有選中的項(xiàng),則選擇框的 value 屬性保存空字符串。
如果有一個(gè)選中項(xiàng),而且該項(xiàng)的 value 特性已經(jīng)在 HTML 中指定,則選擇框的 value 屬性等于選中項(xiàng)的 value 特性。即使 value 特性的值是空字符串,也同樣遵循此條規(guī)則。
如果有一個(gè)選中項(xiàng),但該項(xiàng)的 value 特性在 HTML 中未指定,則選擇框的 value 屬性等于該項(xiàng)的文本。
如果有多個(gè)選中項(xiàng),則選擇框的 value 屬性將依據(jù)前兩條規(guī)則取得第一個(gè)選中項(xiàng)的值。
在 DOM 中,每個(gè)元素都有一個(gè) HTMLOptionElement 對象表示。為便于訪問數(shù)據(jù),HTMLOptionElement 對象添加了下列屬性:
index:當(dāng)前選項(xiàng)在 options 集合中的索引。
label:當(dāng)前選項(xiàng)的標(biāo)簽;等價(jià)于 HTML 中的 label 特性。
selected:布爾值,表示當(dāng)前選項(xiàng)是否被選中。將這個(gè)屬性設(shè)置為 true 可以選中當(dāng)前選項(xiàng)。
text:選項(xiàng)的文本。
value:選項(xiàng)的值(等價(jià)于 HTML 中的 value 特性)。
推薦使用選項(xiàng)屬性取得選擇框中的文本和值。
var selectbox = document.forms[0]. elements["location"];
//推薦
var text = selectbox.options[0].text; //選項(xiàng)的文本
var value = selectbox.options[0].value; //選項(xiàng)的值
3.1 選擇選項(xiàng)
(1)對于只允許選擇一項(xiàng)的選擇框,訪問選中項(xiàng)的最簡單方式,就是使用選擇框的 selectedIndex 屬性 ;
var selectedOption = selectbox.options[selectbox.selectedIndex];
(2)另一種選擇選項(xiàng)的方式,就是取得對某一項(xiàng)的引用,然后將其 selected 屬性 設(shè)置為 true。
//下面的代碼會(huì)選中選擇框中的第一項(xiàng):
selectbox.options[0].selected = true;
//這個(gè)函數(shù)可以返回給定選擇框中選出項(xiàng)的一個(gè)數(shù)組
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;
}
3.2 添加選項(xiàng)
(1)第一種方式就是使用如下所示的DOM 方法 。
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("Option text"));
newOption.setAttribute("value", "Option value");
selectbox.appendChild(newOption);
(2)第二種方式是使用 Option 構(gòu)造函數(shù) 來創(chuàng)建新選項(xiàng),Option 構(gòu)造函數(shù)接受兩個(gè)參數(shù):文本( text)和值( value);第二個(gè)參數(shù)可選。
var newOption = new Option("Option text", "Option value");
selectbox.appendChild(newOption); //在 IE8 及之前版本中有問題
(3)第三種添加新選項(xiàng)的方式是使用選擇框的 add()方法 。 DOM 規(guī)定這個(gè)方法接受兩個(gè)參數(shù):要添加的新選項(xiàng)和將位于新選項(xiàng)之后的選項(xiàng)。如果想在列表的最后添加一個(gè)選項(xiàng),應(yīng)該將第二個(gè)參數(shù)設(shè)置為null。要想編寫跨瀏覽器的代碼,為第二個(gè)參數(shù)傳入 undefined,就可以在所有瀏覽器中都將新選項(xiàng)插入到列表最后了。
var newOption = new Option("Option text", "Option value");
selectbox.add(newOption, undefined); //最佳方案
3.3 移除選項(xiàng)
(1)首先,可以使用 DOM 的 removeChild() 方法,為其傳入要移除的選項(xiàng)
selectbox.removeChild(selectbox.options[0]); //移除第一個(gè)選項(xiàng)
(2)可以使用選擇框的 remove() 方法。這個(gè)方法接受一個(gè)參數(shù),即要移除選項(xiàng)的索引
selectbox.remove(0); //移除第一個(gè)選項(xiàng)
(3)最后一種方式,就是將相應(yīng)選項(xiàng)設(shè)置為 null
selectbox.options[0] = null; //移除第一個(gè)選項(xiàng)
//要清除選擇框中所有的項(xiàng)
function clearSelectbox(selectbox){
for(var i=0, len=selectbox.options.length; i < len; i++){
selectbox.remove(i);
}
}
3.4移動(dòng)和重排選項(xiàng)
(1) DOM 的appendChild() 方法,就可以將第一個(gè)選擇框中的選項(xiàng)直接移動(dòng)到第二個(gè)選擇框中。如果為 appendChild()方法傳入一個(gè)文檔中已有的元素,那么就會(huì)先從該元素的父節(jié)點(diǎn)中移除它,再把它添加到指定的位置。 (2)要將選擇框中的某一項(xiàng)移動(dòng)到特定位置,最合適的 DOM 方法就是 insertBefore() ; appendChild()方法只適用于將選項(xiàng)添加到選擇框的最后。
4、表單序列化
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": //復(fù)選框
if (!field.checked){
break;
}
/* 執(zhí)行默認(rèn)操作 */
default:
//不包含沒有名字的表單字段
if (field.name.length){
parts.push(encodeURIComponent(field.name) + "=" +
encodeURIComponent(field.value));
}
}
}
return parts.join("&");
}
5、富文本編輯
所見即所得。這一技術(shù) 的本質(zhì),就是在頁面中嵌入一個(gè)包含空 HTML 頁面的 iframe。通過設(shè)置 designMode 屬性 ,這個(gè)空白的 HTML 頁面可以被編輯,而編輯對象則是該頁面
元素的 HTML 代碼。 designMode 屬性有兩個(gè)可能的值: "off"(默認(rèn)值)和"on"。
5.1 使用contenteditable屬性
另一種編輯富文本內(nèi)容的方式是使用名為 contenteditable 的特殊屬性,這個(gè)屬性也是由 IE 最早實(shí)現(xiàn)的。 可以把 contenteditable 屬性應(yīng)用給頁面中的任何元素,然后用戶立即就可以編輯該元素。
contenteditable 屬性有三個(gè)可能的值: "true"表示打開、 "false"表示關(guān)閉, "inherit"表示從父元素那里繼承(因?yàn)榭梢栽?contenteditable 元素中創(chuàng)建或刪除元素)。
5.2 操作富文本
與富文本編輯器交互的主要方式,就是使用 document.execCommand() ??梢詾?document.execCommand()方法傳遞 3 個(gè)參數(shù):要執(zhí)行的命令名稱、表示瀏覽器是否應(yīng)該為當(dāng)前命令提供用戶界面的一個(gè)布爾值和執(zhí)行命令必須的一個(gè)值(如果不需要值,則傳遞 null)。為了確??鐬g覽器的兼容性,第二個(gè)參數(shù)應(yīng)該始終設(shè)置為 false,因?yàn)?Firefox 會(huì)在該參數(shù)為 true 時(shí)拋出錯(cuò)誤。
//可以在任何時(shí)候使用這些命令來修改富文本區(qū)域的外觀,如下面的例子所示。
//轉(zhuǎn)換粗體文本
frames["richedit"].document.execCommand("bold", false, null);
//轉(zhuǎn)換斜體文本
frames["richedit"].document.execCommand("italic", false, null);
//創(chuàng)建指向 www.wrox.com 的鏈接
frames["richedit"].document.execCommand("createlink", false,
"http://www.wrox.com");
//格式化為 1 級標(biāo)題
frames["richedit"].document.execCommand("formatblock", false, "");
除了命令之外,還有一些與命令相關(guān)的方法。第一個(gè)方法就是 queryCommandEnabled() ,可以用它來檢測是否可以針對當(dāng)前選擇的文本,或者當(dāng)前插入字符所在位置執(zhí)行某個(gè)命令。這個(gè)方法接收一個(gè)參數(shù),即要檢測的命令。如果當(dāng)前編輯區(qū)域允許執(zhí)行傳入的命令,這個(gè)方法返回true,否則返回 false。
另外, queryCommandState() 方法用于確定是否已將指定命令應(yīng)用到了選擇的文本。
最后一個(gè)方法是 queryCommandValue() ,用于取得執(zhí)行命令時(shí)傳入的值(即前面例子中傳給document.execCommand()的第三個(gè)參數(shù))。
5.3 富文本選區(qū)
在富文本編輯器中,使用框架( iframe)的 getSelection()方法,可以確定實(shí)際選擇的文本。這個(gè)方法是 window 對象和 document 對象的屬性,調(diào)用它會(huì)返回一個(gè)表示當(dāng)前選擇文本的 Selection對象。每個(gè) Selection 對象都有下列屬性:
anchorNode:選區(qū)起點(diǎn)所在的節(jié)點(diǎn)。
anchorOffset:在到達(dá)選區(qū)起點(diǎn)位置之前跳過的 anchorNode 中的字符數(shù)量。
focusNode:選區(qū)終點(diǎn)所在的節(jié)點(diǎn)。
focusOffset: focusNode 中包含在選區(qū)之內(nèi)的字符數(shù)量。
isCollapsed:布爾值,表示選區(qū)的起點(diǎn)和終點(diǎn)是否重合。
rangeCount:選區(qū)中包含的 DOM 范圍的數(shù)量。
Selection 對象還有下列方法:
addRange(range):將指定的 DOM 范圍添加到選區(qū)中。
collapse(node, offset):將選區(qū)折疊到指定節(jié)點(diǎn)中的相應(yīng)的文本偏移位置。
collapseToEnd():將選區(qū)折疊到終點(diǎn)位置。
collapseToStart():將選區(qū)折疊到起點(diǎn)位置。
containsNode(node):確定指定的節(jié)點(diǎn)是否包含在選區(qū)中。
deleteFromDocument(): 從文檔中刪除選區(qū)中的文本, 與document.execCommand("delete",false, null)命令的結(jié)果相同。
extend(node, offset):通過將 focusNode 和 focusOffset 移動(dòng)到指定的值來擴(kuò)展選區(qū)。
getRangeAt(index):返回索引對應(yīng)的選區(qū)中的 DOM 范圍。
removeAllRanges():從選區(qū)中移除所有 DOM 范圍。實(shí)際上,這樣會(huì)移除選區(qū),因?yàn)檫x區(qū)中至少要有一個(gè)范圍。
reomveRange(range):從選區(qū)中移除指定的 DOM 范圍。
selectAllChildren(node):清除選區(qū)并選擇指定節(jié)點(diǎn)的所有子節(jié)點(diǎn)。
toString():返回選區(qū)所包含的文本內(nèi)容
5.4 表單與富文本
由于以這種方式構(gòu)建的富文本編輯器并不是一個(gè)表單字段,因此在將其內(nèi)容提交給服務(wù)器之前,必須將 iframe 或 contenteditable 元素中的 HTML 復(fù)制到一個(gè)表單字段中。 下面就是通過
//表單的 onsubmit 事件處理程序?qū)崿F(xiàn)上述操作的代碼。
EventUtil.addHandler(form, "submit", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.elements["comments"].value = frames["richedit"].document.body.innerHTML;
});