原文:http://blog.csdn.net/blinkstar824/article/details/7362803
在 HTML 中,有兩種方式來(lái)表現(xiàn)文本框:一種是使用 <input> 元素的單行文本框,另一種是使用 <textarea> 的多行文本框。這兩個(gè)控件非常相似,而且多數(shù)時(shí)候的行為也差不多。不過(guò),它們之間仍然存在一些重要的區(qū)別。
要表現(xiàn)文本框,必須將 <input> 元素的 type 特性設(shè)置為 "text" 。而通過(guò)設(shè)置 size 特性,可以指定文本框中能夠顯示的字符數(shù)。通過(guò) value 特性,可以設(shè)置文本框的初始值,而 maxlength 特性則用于指定文本框可以接受的最大字符數(shù)。如果要?jiǎng)?chuàng)建一個(gè)文本框,讓它能夠顯示 25 個(gè)字符,但輸入不能超過(guò) 50 個(gè)字符,可以使用以下代碼:
<input type="text" size="25" maxlength="50" value="initial value">
相對(duì)而言,<textarea> 元素則始終會(huì)呈現(xiàn)為一個(gè)多行文本框。要指定文本框的大小,可以使用 rows 和 cols 特性。其中,rows 特性指定的是文本框的字符行數(shù),而 cols 特性指定的是文本框的字符列數(shù) (類似于 <input> 元素的 size 特性)。與 <input> 元素不同,<textarea>的初始值必須要放在 <textarea> 和 </textarea> 之間,如下面的例子所示:
<textarea rows="25" cols="5">initial value</textarea>
另一個(gè)與 <input> 的區(qū)別在于,不能在 HTML 中給 <textarea> 指定最大字符數(shù)。
無(wú)論這兩種文本框在標(biāo)記中有什么區(qū)別,但它們都會(huì)將用戶輸入的內(nèi)容保存在 value 屬性中??梢酝ㄟ^(guò)這個(gè)屬性讀取和設(shè)置文本框的值,如下面的例子所示:
var textbox = document.form[0].elements["textbox1"];
alert(textbox.value);
textbox.value = "Some new value";
我們建議讀者像上面這樣使用 value 屬性讀取或設(shè)置文本框的值,不建議使用標(biāo)準(zhǔn)的 DOM 方法。換句話說(shuō),不要使用 setAttribute() 設(shè)置 <input> 元素的 value 特性,也不要去修改 <textarea> 元素的第一個(gè)子節(jié)點(diǎn)。原因很簡(jiǎn)單:對(duì) value 屬性所作的修改,不一定會(huì)反映在 DOM 中。因此,在處理文本框的值時(shí),最好不要使用 DOM 方法。
上述兩種文本框都支持 select() 方法,這個(gè)方法用于選擇文本框中的所有文本。在調(diào)用 select() 方法時(shí),大多數(shù)瀏覽器 (Opera 除外) 都會(huì)將焦點(diǎn)設(shè)置到文本框中。這個(gè)方法不接受參數(shù),可以在任何時(shí)候被調(diào)用。下面來(lái)看一個(gè)例子:
var textbox = document.forms[0].elements["textbox1"];
textbox.select();
在文本框獲得焦點(diǎn)時(shí)選擇其所有文本,這是一種非常常見的做法,特別是在文本框包含默認(rèn)值的時(shí)候。因?yàn)檫@樣做可以讓用戶不必一個(gè)一個(gè)地刪除文本。下面展示了實(shí)現(xiàn)這一操作的代碼:
EventUtil.addHandler(textbox, "focus", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
將上面的代碼應(yīng)用到文本框之后,只要文本框獲得焦點(diǎn),就會(huì)選擇其中所有的文本。這種技術(shù)能夠較大幅度地提升表單的易用性。
1.選擇 (select) 事件
與 select() 方法對(duì)應(yīng)的,是一個(gè) select 事件。在選擇了文本框中的文本時(shí),就會(huì)觸發(fā) select 事件。不過(guò),到底什么時(shí)候觸發(fā) select 事件,還會(huì)因?yàn)g覽器而異。在 Opera、Firefox、Chrome 和 Safari 中,只有用戶選擇了文本 (而且要釋放鼠標(biāo)),才會(huì)觸發(fā) select 事件。而在 IE 中,只要用戶選擇了一個(gè)字母 (不必釋放鼠標(biāo)),就會(huì)觸發(fā) select 事件。另外,在 IE 、Firefox 和 Opera 中,也會(huì)在調(diào)用 select() 方法時(shí)觸發(fā) select 事件;但在 Safari 和 Chrome 中則不會(huì)。因此,要想編寫跨瀏覽器的代碼,必須得像下面這樣手工取得對(duì)事件目標(biāo)的引用:
var textbox = document.forms[0].elements["textbox1"];
EventUtil.addHandler(textbox, "select", function(event) {
var target = document.forms[0].elements["textbox1"];
alert("Text selected");
});
這里,通過(guò)在事件處理程序中重新獲取對(duì)文本框的引用,可以避免在跨瀏覽器時(shí)出現(xiàn)問題。
Firefox 2 中存在 bug,其 select 事件的目標(biāo)始終是 document。Firefox 3 修改了這個(gè) bug 。
2.取得選擇的文本
雖然通過(guò) select 事件我們可以知道用戶什么時(shí)候選擇了文本,但仍然不知道用戶選擇了什么文本。沒有任何標(biāo)準(zhǔn)就如何取得選擇的文本作出規(guī)定,因此就出現(xiàn)了一些事實(shí)標(biāo)準(zhǔn)。其中,F(xiàn)irefox 的方案最受開發(fā)人員認(rèn)可。Firefox 為文本框添加了兩個(gè)屬性: selectionStart 和 selectionEnd 。這兩個(gè)屬性中保存的是基于 0 的數(shù)值,表示所選擇文本的范圍。因此,要取得用戶在文本框中選擇的文本,可以使用如下代碼:
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
}
Firefox、Safari、Chrome 和 Opera 都支持這兩個(gè)屬性。IE 不支持這兩個(gè)屬性,而是提供了另一種方案。
IE有一個(gè) document.selection 對(duì)象,其中保存著用戶在整個(gè)文檔范圍內(nèi)選擇的文本信息;也就是說(shuō),無(wú)法確定用戶選擇的是頁(yè)面中哪個(gè)部位的文本。不過(guò),在與 select 事件一起使用的時(shí)候,可以假定是用戶選擇了文本框的文本,因而觸發(fā)了該事件。要取得選擇的文本,首先必須建一個(gè)范圍 (第11 章討論過(guò)),然后再將文本從其中提取出來(lái),如下面的例子所示:
function getSelectedText (textbox) {
if (document.selection) {
return document.selection.createRange().text;
} else {
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
}
}
這里修改了前面的函數(shù),包括了在 IE 中取得選擇文本的代碼。注意,調(diào)用 document.selection 時(shí),不需要考慮 textbox 參數(shù)。
我們經(jīng)常會(huì)要求用戶在文本框中輸入特定的數(shù)據(jù),或者輸入特定格式的數(shù)據(jù)。例如,必須包含某些字符,或者必須匹配某種模式。由于文本框在默認(rèn)情況下沒有提供多少驗(yàn)證數(shù)據(jù)的手段,因此必須使用 JavaScript 來(lái)完成此類過(guò)濾輸入的操作。而綜合運(yùn)用事件和 DOM 手段,就可以將普通的文本框轉(zhuǎn)換成能夠理解用戶輸入數(shù)據(jù)的功能型控件。
1.屏蔽字符
有時(shí)候,我們需要用戶輸入的文本中包含或不包含某些字符。例如,電話號(hào)碼中不能包含非數(shù)值字符。如前所述,響應(yīng)向文本框中插入字符操作的是 keypress 事件。因此,可以通過(guò)阻止這個(gè)事件的默認(rèn)行為來(lái)屏蔽此類字符。在極端的情況下,可以通過(guò)下列代碼屏蔽所有按鈕操作:
EventUtil.addHandler(textbox, "keypress", function(event){
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
});
運(yùn)行以上代碼后,由于所有按鍵操作都將被屏蔽,結(jié)果會(huì)導(dǎo)致文本框變成只讀的。如果只想屏蔽特定的字符,則需要檢測(cè) keypress 事件對(duì)應(yīng)的字符編碼,然后再?zèng)Q定如何響應(yīng)。例如,下列代碼只允許用戶輸入數(shù)值:
EventUtil.addHandler(textbox, "keypress", function(event){
event = EventUtil.getTarget(event);
var target = EventUtil.getTarget(event);
var charCode = EventUtil.getCharCode(event);
if (!/\d/.test(String.fromCharCode(charCode))) {
EventUtil.preventDefault(event);
}
});
在這個(gè)例子中,我們使用 EventUtil.getCharCode() 實(shí)現(xiàn)了跨瀏覽器取得字符編碼。然后,使用 String.fromCharCode() 將字符編碼轉(zhuǎn)換成字符串,再使用正則表達(dá)式 /\d/ 來(lái)測(cè)試該字符串,從而確定用戶輸入的是不是數(shù)值。如果測(cè)試失敗,那么就使用 EventUtil.preventDefault() 屏蔽按鍵事件。結(jié)果,文本框就會(huì)忽略所有輸入的非數(shù)值。
雖然理論上只應(yīng)該在用戶按下字符鍵時(shí)才觸發(fā) keypress 事件,但有些瀏覽器也會(huì)對(duì)其他鍵觸發(fā)此事件。Firefox 和 Safari(3.1版本以前) 會(huì)對(duì)向上鍵、向下鍵、退格鍵和刪除鍵觸發(fā) keypress 事件;Safari 3.1 及更新版本則不會(huì)對(duì)這些鍵觸發(fā) keypress 事件。這意味著,僅考慮到屏蔽不是數(shù)值的字符還不夠,還要避免屏蔽這些極為常用和必要的鍵。所幸的是,要檢測(cè)這些鍵并不困難。在 Firefox 中,所有由非字符鍵觸發(fā)的 keypress 事件對(duì)應(yīng)的字符編碼為 0 ,而在 Safari 3 以前的版本中,對(duì)應(yīng)的字符編碼全部為 8 。為了讓代碼更通用,只要不屏蔽那些字符編碼小于 10 的鍵即可。故而,可以將上面的函數(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){
EventUtil.preventDefault(event);
}
});
這樣,我們的事件處理程序就可以適用所有瀏覽器了,即可以屏蔽非數(shù)字字符,但不屏蔽那些也會(huì)觸發(fā) keypress 事件的基本按鍵。
除此之外,還有一個(gè)問題需要處理:復(fù)制、粘帖及其他操作還要用到 Ctrl 鍵。在除 IE 之外的所有瀏覽器中,前面的代碼也會(huì)屏蔽 Ctrl+C、Ctrl+V,以及其他使用 Ctrl 的組合鍵。因此,最后還要添加一個(gè)檢測(cè)條件,以確保用戶沒有按下 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);
}
});
經(jīng)過(guò)最后一點(diǎn)修改,就可以確保文本框的行為完全正常了。在這個(gè)例子的基礎(chǔ)上加以修改和調(diào)整,就可以將同樣的技術(shù)運(yùn)用用放過(guò)和屏蔽任何輸入文本框的字符。
聯(lián)系客服