親密接觸單選按鈕、復(fù)選框和JavaScript的一些有趣的事情
我將以對象模型和一些常用對象開始,因?yàn)镴avaScript里的一切都是從對象展開的。記住,本文不只是關(guān)于JavaScript的,它是關(guān)于Notes/Domino中的JavaScript的。 窗口 窗口有它的屬性,比如它的地址(也就是它的URL),瀏覽器底部的狀態(tài)條上的文字等等;它也有方法,比如打開和關(guān)閉。通常來說,因?yàn)榇翱谠趯ο髮哟蔚捻攲?,JavaScript就假設(shè)Window已經(jīng)存在了,你不必去刻意寫上它,也就是說“window.location”和“l(fā)ocation”的作用是相同的。 窗口里是Web頁面,它的對象層次從文檔(document)開始。你可以用Window.document來引用它,或者就是簡單的document。每個窗口只有一個文檔(document)。依據(jù)你的瀏覽器的不同,文檔(document)有幾個變化多樣的選項(xiàng)。在MSIE中,document.all數(shù)組包含了文檔(document)中所有的對象。在Netscape Navigator的某些版本中,你可以訪問document.layers數(shù)組。每一種瀏覽器關(guān)于對象的解釋都不一樣,但是表單數(shù)組(forms array)在所有的瀏覽器中都是可以訪問的。 理論上講,每個文檔(document)包含至少一個表單(form),但是可以包含多個。然而,在Notes中,除非明確寫出用來完成特定功能的HTML代碼(我從來沒那么做過),通常只有一個表單。但是,因?yàn)榭梢杂卸鄠€表單,所以你在引用表單時,還是得通過數(shù)組元素來引用表單,下標(biāo)從0開始。不像LotusScript那樣,用圓括號來括住下標(biāo)數(shù)字,比如doc.CompanyName(0),在JavaScript中你通常會看到引用數(shù)組下標(biāo)的數(shù)字是括在方括號中的。因此,你應(yīng)該用下面的方式引用表單:
或者簡寫成:
嚴(yán)格來說,上面的方法并不是唯一引用表單的方式,下面都是引用表單的合法的表達(dá)式:
然而,你經(jīng)??吹降倪€是帶方括號的方式。注意,我在每行語句的末尾加了分號,這是在JavaScript中和公式語言的相似之處之一。你應(yīng)該在每一條語句的末尾加上分號。和公式語言不同的是,在JavaScript中分號并不總是必需的。有些瀏覽器和其他瀏覽器比起來,它們可以運(yùn)行沒有分號的JavaScript語句,所以,盡管有時你可以不用加分號,但是你最好養(yǎng)成每一條語句都加分號的習(xí)慣。 當(dāng)你接觸到表單后,你就已經(jīng)為訪問你最關(guān)心的元素做好了準(zhǔn)備。表單是域、按鈕、文本、圖像和其他元素的容器,你將在表單中用JavaScript來處理這些元素。 簡單的幾個元素
或者這樣:
在LotusScript中,域的類型對于你要取值(值數(shù)組)的代碼并不重要。不幸的是,這對于JavaScript并不適用。在JavaScript中,不同類型的域除了顯示選項(xiàng)(比如單選框、復(fù)選框或者文本)外,并不像在Notes里那樣,它們是不同的類型的對象,每一個都要用不同的方式去引用。其實(shí),那也不是絕對的,有些對象是相似的,但是引用過程并不像在LotusScript里那么流暢。你會發(fā)現(xiàn),你將花費(fèi)很多時間手動尋找你的代碼中的域(名)錯誤來使它們正常運(yùn)行,那看起來很糟糕。 你首先要知道的一點(diǎn)是:在JavaScript中,沒有所謂的Rich-Text域,在HTML中更沒有。Notes里提供了一個可以放在瀏覽器里的富文本Java(不是JavaScript)小程序,從而可以得到富文本的一些功能,但是你并不能用JavaScript來對它編程,而且它也不是一個真正的HTML對象類型。 更讓Notes開發(fā)人員驚訝的是,在Web上還沒有數(shù)字型或時間型的域。HTML的域都是文本型的。盡管你能用它們來收集數(shù)字信息,如數(shù)量或單價,而保存的數(shù)據(jù)依然是文本。為了像數(shù)字一樣使用它,你必須把它轉(zhuǎn)換成數(shù)字類型。我將在后面詳細(xì)講解它?,F(xiàn)在,要意識到一切都是文本,就像你在Notes的@Prompt對話框里輸入的信息一樣。 圖 1 建立表單 如果你用R5的設(shè)計(jì)器(Designer),請把觸發(fā)按鈕的語言改成JavaScript。如果你像我一樣用R6的設(shè)計(jì)器(Designer),就要稍微麻煩一些。在Notes/Domino6(ND6)中,你可以像在瀏覽器中使用JavaScript一樣在Notes客戶端中使用JavaScript。更重要的是,同一個按鈕在不同的客戶端里能運(yùn)行不同的代碼。在圖2中,你將會看到一些選項(xiàng),你將決定所寫的代碼是在Notes(“客戶端”)還是在瀏覽器(“Web”)里運(yùn)行。 圖 2 圖 3 這個功能當(dāng)你在不同的環(huán)境里運(yùn)行不同的代碼時非常有用,但是當(dāng)你要在兩種環(huán)境里運(yùn)行同樣的代碼時怎么辦呢?當(dāng)然有比拷貝按鈕代碼更好的方法,你可以在右邊的下拉列表中選擇最下面的Common JavaScript來為兩種環(huán)境同時編寫代碼(如圖3)。 在本例中,選擇 在按鈕腳本中,輸入提示用戶CreatedBy域值的代碼。如果你看過前一篇文章,你就知道可以用點(diǎn)來分隔JavaScript里的各個層級元素。你的按鈕腳本應(yīng)該如下所示:
需要注意的是,JavaScript區(qū)分大小寫。這個規(guī)則不只對JavaScript元素(文檔、表單等)有效(首字母小寫),對域的名字同樣有效。你在域中用的什么大小寫效果,在代碼中必須如實(shí)反映。在瀏覽器中試驗(yàn)一下按鈕的功能[Design>Preview in Web Browser>Internet Explorer(或者你自己的瀏覽器)]。如果你使用Domino R6的設(shè)計(jì)器(Designer),你可以在Notes客戶端中進(jìn)行試驗(yàn)(Design>Preview in Notes)。 圖 4 如果你在用一個本地?cái)?shù)據(jù)庫進(jìn)行試驗(yàn)(對應(yīng)的是在服務(wù)器上),在瀏覽器中你看到的用戶名將是“Anonymous”,而不是你的名字,然而在Notes客戶端中卻是你的名字。原因是當(dāng)你用Web頁面的方式訪問本地?cái)?shù)據(jù)庫時,你沒有登錄到服務(wù)器,瀏覽器不知道你是誰。但是在Notes中,不論是本地還是服務(wù)器,你必須登錄才能使用系統(tǒng)。這就是兩種客戶端之間微妙的差別。 另一個區(qū)別是在Web上沒有計(jì)算域,但并不意味著你不能在你的表單里加入計(jì)算域。你可以加入計(jì)算域,計(jì)算值將會在Web頁中顯示,除非域是隱藏的。關(guān)鍵是即使域就在那里顯示,而HTML通常的處理是沒有定義域。如果你把CreatedBy域改成計(jì)算域而不是可編輯的,在重新測試時你就會明白我所說的意思,你會得到和圖4類似的提示信息。 但是當(dāng)你在Notes客戶端(R6)里運(yùn)行時,即使是計(jì)算域也沒有任何錯誤。坦白地說,我還沒有對這個功能是好還是壞下結(jié)論,但那就是我們所得到的結(jié)果。 這里產(chǎn)生的錯誤非常重要,你要開始理解JavaScript里產(chǎn)生的錯誤,因?yàn)樗鼘δ愕拇a調(diào)試有很大的用處。那么當(dāng)它提示你“document.forms.0.CreatedBy.value”為null值或不是對象時,意味著沒有得到你想要的數(shù)據(jù)。 當(dāng)你返回到瀏覽器里,在背景上單擊右鍵,選擇“查看源文件”時,你會看到隱藏在Web頁面下的HTML代碼。你簡單瀏覽代碼時,會看到對按鈕和計(jì)算域的引用,如下所示:
當(dāng)你對頁面進(jìn)行過排版的話,你的代碼里可能會有字體、段落或其他的標(biāo)記混雜在按鈕和計(jì)算域的代碼里。那些是格式化文檔用的,在此處的討論中可以略過不看。注意看“Anonymous”是表單上的另一個單詞,它沒有任何的標(biāo)記在兩旁來提示你它是從域產(chǎn)生的。在源代碼中,Anonymous和“Created By”沒有任何區(qū)別:兩個在域前面的靜態(tài)文本(如果你已經(jīng)登錄,你將看到你的名字而不是Anonymous)。 為了比較一下,把CreatedBy域改回可編輯文本,保存表單,回到瀏覽器并刷新頁面,再看頁面的源文件,將會如下所示:
代替單詞Anonymous(或是你的名字)的是域的HTML代碼(或者嚴(yán)格地講,是HTML的文本輸入框)。它的名字是“CreatedBy”,值是“Anonymous”。這些是通過JavaScript能取得的屬性,而普通的文本卻沒有這些屬性。所以你不能用JavaScript來引用計(jì)算域,至少在瀏覽器中如此。還有一點(diǎn)令人迷惑的就是當(dāng)文檔在非編輯狀態(tài)下時,即使是可編輯域,也不能用JavaScript來引用它。換句話說,當(dāng)你保存了文檔再次打開,但沒有把它設(shè)置成編輯模式時,頁面的HTML代碼將和CreatedBy域是計(jì)算域時相同。另外一個關(guān)于JavaScript的有趣的現(xiàn)象是:在Domino以外,我們沒有太多的機(jī)會去處理表單的編輯和非編輯狀態(tài),而對于我們Domino開發(fā)者來說,這可是個大問題。 你注意到按鈕和域都轉(zhuǎn)換成輸入對象了嗎?那就是HTML的工作方式。使人迷惑的是兩個對象都有value這個屬性。對于按鈕,value是“Get editable field value”,我想應(yīng)該是按鈕的標(biāo)簽,但是域的value值卻是它的實(shí)際值。一些其他類型的對象同時有value屬性和text屬性。如果你像我一樣,那么你有時就會搞不清楚什么是什么!就我的經(jīng)驗(yàn)而談,最簡單的辦法是讀Web頁面的HTML代碼。 多值
把按鈕命名為“Get multiple values”并鍵入如下的JavaScript代碼:
你可以用不同的分隔符來改變此域的值,但是當(dāng)你單擊按鈕時,你會注意到,不論你用什么分隔符,提示你的總是域的所有值。這和在Notes客戶端中運(yùn)行的@Formulas和LotusScript形成了對比。用@Prompt,你得到的提示只是域的第一個值:“A”。你用LotusScript同樣也只能顯示一個值,但是你要指定數(shù)組下標(biāo),否則將得到一個錯誤提示。公式和LotusScript都不能在提示語句中得到多值域的所有值。 原因就是,在Notes的語言中,確實(shí)有多個值在域中。對于HTML和JavaScript來說,只有一個值。再次看Web頁面的源代碼你會發(fā)現(xiàn)和下面類似的代碼:
注意它的值是用“一對”雙引號引起來的帶分隔符的值。以后將會詳細(xì)討論如何分隔單獨(dú)的值,但現(xiàn)在,你應(yīng)該意識到多值在Web上并不是確切的多值(至少對于文本輸入框是如此)。其他類型域的處理方式和文本域?qū)煌? 單選按鈕 在表單上,加入另一個新域,名字為“RadioButtn”。正像它的名字一樣,把它改成單選框類型的域。在域?qū)傩源翱诘牡诙€標(biāo)簽中,輸入下列選項(xiàng)和別名(圖5): 圖 5
把此域的缺省值設(shè)成第一個選項(xiàng)的別名,也就是帶引號的字母“A”。現(xiàn)在在瀏覽器里預(yù)覽表單,再看源文件,你會看到單選按鈕的代碼和正常域的代碼有很大區(qū)別。HTML代碼看起來將和下面的類似:
在這里你要注意一些要點(diǎn)。首先,所有的4個單選按鈕對象有同一個名字:RadioButtn,這樣一來,HTML和JavaScript就知道它們是同一個數(shù)組里的對象。其次,每個選項(xiàng)的值是選項(xiàng)的別名,并不是看到的文字(例如“One”、“Two”等)。這和在Notes中保存的是別名是一樣的,保存的不是看到的文本(當(dāng)然如果沒有別名的話,保存的值和文本就是一樣的了)。最后,你選中第一個選項(xiàng)的方法是在HTML語句中用的“checked”單詞,它被加在了第一個單選按鈕的語句里。 如果你再加入另外的一個按鈕,用和取其他兩個域值同樣的方法來取RadioButtn的值的話,你會得到一個奇怪的錯誤,也就是用下面的代碼:
你將會看到一個提示“undefined”的錯誤對話框(如圖6)。 圖 6 這里的問題并不是沒有定義它的值。畢竟如上面所示,單選按鈕的代碼中共有4個值。也就是說,問題出在RadioButtn本身,至少是現(xiàn)在用在這里的那個。單選按鈕是一個輸入選項(xiàng)的數(shù)組,如果你想要知道其中一個元素的值,必須指定是哪一個,試試下面的代碼:
好,返回的是當(dāng)前域的值“A”,但是當(dāng)你選擇其他的選項(xiàng)時再單擊按鈕,你得到的依然是“A”,而不是你所選擇的值,還是不太妙。 為了得到選擇的選項(xiàng)的值,首先要知道哪個選項(xiàng)被選中了,然后在alert語句中,用那個選中的選項(xiàng)的下標(biāo)值來正確地引用當(dāng)前選項(xiàng)的值。也就是說,如果第一個選項(xiàng)被選中,你應(yīng)該取RadioButtn[0].value,如果第二個選項(xiàng)被選中,你就應(yīng)該取RadioButtn[1].value,依此類推。 在JavaScript中,某些類型的域具有selectedIndex屬性,代表當(dāng)前選中選項(xiàng)的數(shù)組下標(biāo)值。然而單選按鈕并不是那么幸運(yùn),同樣,復(fù)選框也沒能逃脫厄運(yùn)。要想得到當(dāng)前選中的單選按鈕的值,你必須在RadioButtn數(shù)組元素中查找“checked”屬性。和LotusScript相比,LotusScript就能像操作其他類型的域一樣來取得單選按鈕當(dāng)前被選中的值。這是一件非常麻煩的事,但是,它就是那樣的。 下面是按鈕的代碼:
這里馬上就出現(xiàn)了幾個新概念,讓我花點(diǎn)兒時間來解釋一下。首先,如果你讀過前面那篇文章,你就會知道“var”是在JavaScript里用來聲明變量或給變量賦值用的,就好比LotusScript里的“Dim”和“Set”。既然這樣,為了避免一遍一遍地輸入document.forms[0],我就把document.forms[0]賦給變量doc以備后用:
下面是循環(huán),循環(huán)體中沒有代碼時的樣子如下:
你是不是有點(diǎn)眼花繚亂?我以前每次看到類似這樣的代碼就眼暈,但是它并不像它看起來那么糟。首先,花括號只是用來包含循環(huán)體的。JavaScript的for循環(huán)有三個選項(xiàng):
首先是i=0,很簡單,我使用了變量i并且它的初始值為0。 第二部分: 循環(huán)體中的第三個參數(shù):i++,對于LotusScript開發(fā)人員來說是一個低級錯誤。這是在JavaScript中的簡寫方式,i++的值和i=i+1的值是一樣的。實(shí)際上,你可以在循環(huán)中用兩種形式的任何一種,所以下面這種寫法和上面的寫法是等價的:
i=i+1同樣可以正常運(yùn)行,但是問題是沒有人那么做,因?yàn)槟懔?xí)慣i++后,它更短小、更簡單。它的價值在于,你還可以寫i--,和i=i-1是一樣的,當(dāng)然,在這個循環(huán)里它不能運(yùn)行。用i++你還可以做許多看起來很有趣的事情,但那是以后的事了。 再來看循環(huán):三個參數(shù)用分號分隔并由圓括號包圍,循環(huán)體代碼用花括號包圍,循環(huán)體中是一個if語句:
這里的判斷真假的語句同樣也用圓括號包圍。試驗(yàn)中的doc.RadioButtn[i].checked看起來沒有提供充足的信息,但它和循環(huán)一起構(gòu)成了一個JavaScript的簡寫方式。如果用LotusScript的方式呢?我首先會去檢查當(dāng)前的RadioButton元素是不是等于checked,像下面的方式:
由于checked是一個屬性而不是一個值,所以上面的代碼不能正確運(yùn)行。你還會注意到在HTML中它并沒有用引號引起來。其實(shí),checked是一種"是"或者"不是"的東西。更準(zhǔn)確一點(diǎn)說,它不是真就是假,所以那個if語句的意思就是:如果RadioButtn的這個元素是checked(被選中的),即:為真,那么就做下面的事情……這里的試驗(yàn)看起來有點(diǎn)奇怪,因?yàn)槭冀K沒有提到真假。如果那讓你感到不舒服,你還可以很輕松地這樣寫if語句:
注意這里的true全部是小寫而且有兩個等號。和LotusScript中不同,JavaScript里的等號(=)只是用來把一個值賦給另一個什么東西:
為了比較兩個項(xiàng)目是否相等,你必須使用兩個等號。在我的頭腦里,我想它的意思是: 最后,在if語句里是一個alert語句,緊跟著一個break。break就是JavaScript里的Exit For。它終止循環(huán),因?yàn)橐粋€單選按鈕只能有一個選項(xiàng)被選中。 如果你把所有的代碼都放入按鈕里,你就會看到無論你選擇單選按鈕的哪個選項(xiàng),單擊按鈕后都能正確的顯示出選項(xiàng)的值。非常棒,現(xiàn)在你對JavaScript已經(jīng)入門了。 復(fù)選框和單選按鈕類似。在表單上,復(fù)制單選按鈕域并改名為"CheckBx",更改域的類型為"CheckBox(復(fù)選框)",保存表單,刷新Web頁面并查看源文件。你將看到復(fù)選框的HTML代碼和RadioButtn的幾乎一模一樣:
真正的區(qū)別不是域名,而是類型是復(fù)選框,不是單選按鈕。另外一個區(qū)別就是你可以選擇復(fù)選框中的多個值,盡管你還要像操作單選按鈕那樣遍歷整個復(fù)選框來確定哪個選項(xiàng)被選中,但是你不能在全部檢查完是否選中之前停止遍歷動作。按鈕中用來檢查復(fù)選框選中的代碼會像下面的樣子:
我確信到現(xiàn)在為止,你應(yīng)該多多少少熟悉這些代碼了,因?yàn)檫@和單選按鈕基本一樣,除了域名的改變和去掉了"bread"語句。在一個實(shí)用的程序中,這些代碼所做的工作比我做的要多得多,但是首先我希望你很舒服地學(xué)完這些基本內(nèi)容。 等待更多的對象
|
![]() |