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