目錄

基本說明: 1. JavaScript 新手入門     2. 為什麼要使用JavaScript    3. JavaScript的定義    

內容解說: 1. 基本入門    2. 檢查輸入資料    3. 檢視數字位元   4. 處理輸入資料     5. 依據模式處理    6. 確認表格    7. 增強Image Map    8. 在瀏覽器儲存資料

實例練習:

 

 


 倘若你已經是老資格的網路族了,相信或許早已碰過JavaScript。網景發展出JavaScript語言(原本稱為LiveScript),以協助開發者在靜態網站上增加互動性。你能運用它創造計算器、搜尋引擎、甚至是互動式訂購表格--當然,只要你知道怎麼做的話。
 
  與其它嚴謹的語法式語言類似的是,你可以花上無數個小時,徹底了解JavaScript的來龍去脈。但是與某些語言不同的是,你能僅靠了解一些JavaScript的基本規則(或是至少學會從我們的範例中,剪下與貼上哪些部份來使用),在兩個小時之內,就可以將其運用在你的網頁上。為了幫助你順利進行,CNET建立了一個Adopt-A-Brain網頁,這個網頁以各種方式來應用JavaScript。跟著我們逐步建立該網站,你就能慢慢學習JavaScript的基本原則 -- 而且有些有用的程式碼,你還可以複製並使用在自己網頁上。

當你閱讀此篇報導的時候,有幾件事需謹記在心。由於我們已經試圖簡化內容,因此我 們假設你至少有些程式設計或語法撰寫的經驗。此外請特別留意,在我們的某些例子當中,得通過在伺服器上執行的程式,才能確實收集到它們的資料。

不過現在,就讓我們從頭說起吧。

 


首先,JavaScript並不是Java,雖然它們共享同一名稱,而且同樣是以物件為主的基礎架構。事實上,網景原本將JavaScript稱為LiveScript。Java的部份是日後加上的,部份原因是為了讓此描述語言(Scripting Language)與更穩固的Sun開發語言之間提供一個具有市場性的連結。

然而,與Java類似的是,JavaScript提供了一種方式,來增加網頁的靈敏與互動性。有了JavaScript,你能夠:

 
處理直接通過HTML介面上向電腦用戶收集的資料,而不必動用伺服器(或是擁有高階Perl、C、或其它程式語言技巧的工程師)
在使用者的電腦中建立與儲存資料
為圖形添增互動性
根據使用者的輸入,立即更動網頁上的元件
以及讓HTML資料與其它網路技術,能更緊密地整合一起(例如Java applets與ActiveX控制程式)

在JavaScript出現之前,對於網頁設計者和硬體商而言,建立互動式網頁要比現在困難得多。收集與處理使用者的資料,需要一種在網路伺服器上執行、被稱為共同閘道介面(common gateway interface,以下簡稱CGI)的指令集(script)。為了使用CGI指令集,你首先得設計一份HTML為主的網頁,內含收集使用者輸入資料的格式。接著,你再以C或Perl語言,來建立(或付錢給某人來建立)一個CGI指令集,好處理在網路伺服器上收集到的輸入資料。

不幸的是,每當使用者觀看網頁並傳送表格時,資料就會從網路瀏覽器傳遞至CGI指令集。CGI指令集接著處理資料,再以HTML為主的新網頁格式,將任何結果送回給使用者。使用者每次一更動網頁格式時,就會發生該種狀況,不但消耗了伺服器CPU動量,由於網路接連來回傳送資料,也浪費了不少時間。

JavaScript透過使用者系統的瀏覽器,進行收集並處理資料的方式,解決了許多此類的問題(即使你之後可能依舊需要將處理過的資料,傳送給CGI指令集)。JavaScript也是一種通譯式語言(interpreted language),這是指它最終並非是某台特定電腦的執行檔。相反地,其程式內容僅會在使用者瀏覽器的JavaScript解讀器中執行。你能立刻編寫JavaScript程式,只要是擁有啟動JavaScript瀏覽器(網景Navigator 2.0版或以上,或是微軟Internet Explorer 3.0或以上)的電腦平台系統,就能夠執行程式。


JavaScript是一種以物件為基準的電腦語言,因此它看起來與C和Pascal這類傳統的程序化語言(procedural language)有些不同。對於初學者來說,程式設計者是以物件、方法以及性質的角度,來形容資料與過程 -- 而不是變數、常式以及敘述。JavaScript的程式設計,則使用了一些特定的條件:

客戶端(client):按照網路為準的應用程式來看,客戶端是指執行網路瀏覽器的電腦。網頁是從網路伺服器載入網路客戶端之中,也就是它們所展示的地方。

事件處理器(event handler):這是一種連接物件和事件的特殊屬性。舉例來說,你可以運用onClick的事件處理器,來連接某一按鈕與滑鼠的點選。在網景的JavaScript參考網頁上,能找到有關事件處理器的清單。

功能函數(function):一組已命名的JavaScript敘述,呼叫功能函數可以立即執行動作。JavaScript擁有好幾組內建的功能函數,不過你也可以自行撰寫,擴充這些功能項目。

事例(instance):某項物件的特定典型。舉例來說,總統可能是一種物件,比爾•柯林頓則是總統的一個事例。同樣地,網頁的某個按鈕(button)也是一項物件,但是我的計算按鈕(myCalculateButton)則是一個事例。

方法(method):某項特定物件所能執行的動作。方法的執行方式就像功能函數,但是它們總與某項特定物件有關。不妨將方法視為動詞。你可以在網景的JavaScript參考網頁上,找到相關的方法清單。

物件模式(object model):為了相同目的而共同執行的一群物件。JavaScript的物件模式,是由製作整個網頁的全部元件所構成。

物件(object):任何事物、想法或觀念,都是一項物件。像JavaScript這類以物件為主的語言,讓使用者能簡單地模仿塑造,並與真實世界中的物件(例如網頁和網頁元件)共同運作。物件一般都是名詞。舉例來說,windows、document以及image,都是JavaScript的物件。

特性(property):用來形容某一物件的單字屬性。比方說,length、name以及target,都是JavaScript的屬性。在JavaScript之中,某一物件的特性,是透過物件的名稱、週期以及特性名稱來定義。除此之外,物件還能納入其它的物件。例如在一份比薩訂單之中,某個稱為pepperoni的物件,就可能包含本身的價格,如下面所示:文件.訂單.辛辣香腸.價格(document.orderform.pepperoni.value)。請瞧瞧網景的JavaScript參考網頁,好尋找可運用的性質清單。

伺服器(server):按照依網路為主的應用程式,伺服器就是執行網路伺服器軟體的電腦。網頁和那些網頁所仰賴的任何程式(例如CGI指令集、Java applets、以及其它等等),都儲存在網路伺服器之中。


 
<HTML>
<HEAD>

這些是開始一份HTML網頁的標準標籤。將JavaScript的程式碼,放入<HEAD>與</HEAD>的標籤之中,是個很不錯的練習,這樣在JavaScript載入之前,才不會不小心叫出一些功能。

 
<SCRIPT LANGUAGE="JavaScript">

這告訴瀏覽器JavaScript即將出現。

 
<!--

這是個安全閘門。介於<!--以及-->下方之間的一切內容,將會被無法解讀JavaScript的瀏覽器忽略。

 
//put your JavaScript statements below

//是JavaScript的註解指示,它告訴瀏覽器的JavaScript解譯器,要忽略接下來的內容。

 
function someFunction() {
some JavaScript statements
}

這就是JavaScript實際上的方向。波浪形的刮號包圍著每條敘述,讓它們與功能中的其它敘述分開。不瞭解這些敘述是什麼?你很快就會知道了。

 
// -->
</SCRIPT>

這些代表我們透過指令集來完成一切,接著回到HTML程式碼。

 
</HEAD>
<BODY>
<FORM>
<!-- put your HTML statements below -->
<INPUT TYPE="button" NAME="someButton" VALUE="Press Me"
  onClick="someFunction()">

在這個例子當中,我們告訴瀏覽器,當使用者點選按鈕時,就執行JavaScript的「someFunction()」函數。

 
</FORM>
</BODY>
</HTML>

那就是網頁的末端。


由於JavaScript是以物件為基準,它處理每種HTML格式元件的方式 -- 也就是每個按鈕、選擇方塊、內容欄位、甚至是格式本身 -- 都是將其視為包含本身資料的個別物件。有了JavaScript,你就能在使用者的電腦上,立即檢視任何HTML物件的資料,並且根據結果做出決定。比方說,運用欄位層級的有效性檢查,你能確認使用者是否在某欄位鍵入數字。

為了執行欄位層級的有效性檢查,你需要定義某個包含有效性檢查邏輯的JavaScript函數,每當使用者空下某個特定的HTML欄位時(按鍵盤離開或是游標移開),就啟動該項函數。一般來說,這代表運用onChange(可以偵察出使用者何時變更欄位)、或是onBlur(偵察使用者何時離開、或是「模糊」某個特定欄位)這類與HTML內容元件有關的事件處理器,來啟動你的函數。

為了顯示這些是如何運作的,讓我們先請使用者挑選他們想贊助的人才數目。接著,我們將檢查確認他們是否有鍵入數值。

首先,我們定義一個稱為exists()的函數(即是「使用者的輸入是否存在」之意)。

 
function exists(userEntry, message) {

exists()函數接受兩個參數。第一個參數「userEntry(使用者輸入)」,代表有效存在的數值。另外一個參數「message(訊息)」,代表倘若數值不存在的話,即會在螢幕上顯示錯誤訊息。

下一步,我們將宣告兩種變數 -- 一個稱為aCharExists,另一個稱為entry(輸入),以作為關鍵變數

 
  var aCharExists = 0;
  var entry = userEntry;

aCharExists變數就是我們的是/否變數。倘若使用者確實輸入資料,我們就將變數數值設定為1,以代表「是」的意思。要是使用者沒有輸入資料,我們將變數數值保持原來的0,來代表「否」的意思。我們會儲存使用者在變數輸入中鍵入的任何字。

JavaScript的變數可以隨意鍵入,這表示你不需在變數宣告之中,立即指定自己想要變數所包含的數值種類(例如以數字、字母為準、或是其它)。相反地,每當你為變數指定數值時,它們可以透過隱喻的方式鍵入。比方說,aCharExists的指定數值為0,其所暗喻的形式就是數字。

如果在exists()的函數之後,再接上一段敘述:

 
  if (entry) {
    for (var i=0; i<entry.length; i++) {
      //spaces don't count as "existence"
      if (entry.charAt(i) != " ") {
        aCharExists = 1;
      }
    }
  }

if敘述確認數值中僅含有空格,那麼整個過程就不會將其視為真正的數值。邏輯的運作即會像下面這個樣子:

 
  if(entry) {

要是輸入數值確實存在,那麼‥‥

 
    for (var i=0; i<entry.length; i++) {
      //spaces don't count as "existence"
      if (entry.charAt(i) != " ") {
        aCharExists = 1;
      }
    }
  }

走過數值,讓我們一個個來檢驗字。var i=0的命令,指定了一個偵測器。只要i輸入字的數量少(如長度特性所指),我們就會對其檢視,以確認非空格的字是否等於字數i。此外,if (entry.charAt(i) !=" "的意思,是「倘若字數i的意思,是「倘若字數i不等於空格時‥‥),那麼當某個字存在,我們則將變數aCharExists設定為1(代表「是的,有字存在」)。接著,我們再回頭進行一次,直到我們檢查過輸入的每個字為止。

最後,該函數的內容即是:

 
  if (!aCharExists) {
    alert(message);
  }
}

這即表示,倘若aCharExists是錯的(如同上面的例子,!代表「錯誤」,或是「不是」),這時就會跳出一個警告訊息。

一旦我們定義了exists()函數,從一個與HTML元件有關的事件處理器上,就可以叫出這個函數,如下面所示:

 
What type of brain do you want? (r=right/l=left)
<INPUT TYPE="text" NAME="typeField"
VALUE="" SIZE=10
  onChange="exists(this.value, 'Please enter
the type of brain.');">

在上面所示的HTML片段中,exists()函數是經由與稱為typeField(內容欄位)的內容元件有關的onChange事件處理器所啟動的。這即代表當使用者改變了輸入欄位的數值,並且從該欄位移開時,它就會啟動exists()函數。倘若輸入欄位沒有數值存在,警告訊息就會提醒使用者輸入數值。

 


現在我們知道使用者有沒有輸入字了。不過,他們輸入的是數字還是字母?大部份的時候,僅知使用者有輸入字是不夠的。相反地,你還想知道他們有沒有輸入正確型態的資料。舉例來說,你可能想知道在信用卡號碼欄位的字,是否確實是數字。你可以運用JavaScript的函數parseInt、parseFloat、以及isNaN,來執行這種有效性檢查。不過,這些函數只能檢查輸入數值的第一位數。下面的例子則是讓你看看,如何建立一個能進行更完整之有效性檢查的函數。

讓我們先建立一個稱為isANumber的新函數:

 
function isANumber(number, message) {
  answer = 1;

首先,我們檢查並確認輸入的數值,是以某個數字作為起始。倘若如此,我們即將答案變數設定等於1,然後繼續下一步驟。

 
  if (!parseFloat(number)) {
    //the first digit wasn't numeric
    answer = 0;
    alert("Please enter a numeric value
for the " + message + " field.");
  }

要是JavaScript的函數parseFloat(),並沒有傳回true的結果(即代表使用者沒有輸入數字),函數就會展示一個警告訊息給使用者。假如第一位是數字,函數就會繼續運作。

 
    else {
    //the first digit was numeric, so check the rest
    for (var i=0; i<number.length; i++) {
      if ((number.charAt(i) != "0")
        && (!parseFloat(number.charAt(i)))) {
          answer = 0;
          alert("Please enter a numeric value
for the " + message + " field.");
          break;
      }
    }
  }
  return answer;
}

別因此感到害怕。這一團程式碼,並不會像外觀那樣的嚇人。在上面的else敘述當中,輸入數字的每一位,都會以迴圈方式分別檢查for (var i=0; i<number.length; i++)。我們已經檢查過第一位數了(以JavaScript的術語來說,就是數位0),因此我們使用i++來代表增加一個變數的意思(在JavaScript之中,i++i=i+1的速記表示)。倘若剩下的數均是數字的話,我們就繼續下去(&&不過是「and」的意思)。假如函數有發現有其它的字,螢幕上就會出現警告訊息,我們就會離開迴圈(連同break的指令)。

當然,假如沒有合適的HTML來叫出它們,這一切的JavaScript都沒有多大意義:

 
Number of brains you'd like to take home
<INPUT TYPE="text" NAME="numberOrdered"
VALUE="" SIZE=10
  onChange="if(this.value) {
    if (!(isANumber(this.value, 'number of
brains'))) {
      this.focus();
    }
  }">

在之前的例子當中,每當使用者改變numberOrdered欄位之中的數值,你可看到與onChange事件處理器相關的所有程式碼,會立刻加以執行。基本上,倘若numberOrdered的欄位中有數值存在,這個數值就會傳送到isANumber()的函數之中,以進行有效性檢查的工作。isANumber()函數會檢查通過的每一位數,而且僅接受阿拉伯數字。要是使用者輸入數字以外的字,他們會看到一個寫著「請在人才數量欄位之中,輸入阿拉伯數字」的訊息。焦點接著會回到數字欄位的變數this.focus()之中,這即代表「將焦點放回目前的格式元件」。


 

一旦你證實了使用者已經輸入有效的資料,此時就是處理它們的時刻。在JavaScript之中,那是件很容易的事。

我們將利用下面的函數來計算認養總額:

 
function calcTotal() {
  document.orderForm.totalPrice.value =
    (document.orderForm.numberOrdered.value
* 15.99);
}

很簡單吧,不是嗎?calcTotal()函數僅取用使用者在numberOrdered欄位所提供的數字,然後將其乘以15.99。

計算出來的總額,接著會出現在「認養總額」的方塊之中。

當然,這裡有用來叫出該函數的HTML:

 
Number of brains you'd like to sponsor
<INPUT TYPE="text" NAME="numberOrdered"
VALUE="" SIZE=10
  onChange="if(this.value) {
    if (!(isANumber(this.value, 'number of
brains'))) {
      this.focus();
    } else {
      calcTotal();
    }
  }">

這將numberOrdered所輸入的數字,送到calcTotal()以進行處理,並假設其通過了isANumber()的檢查。請留意,這個JavaScript的例子,並不需要將資料送回伺服器,以進行最後的處理。你可以運用類似的技巧,來建立任何種類的線上計算機、轉換器、或是小測驗。

請注意,當我們的指令集一開始時,我們定義了orderPlaced(一個通用的變數),並將「false」設定為開始數值。

 
var orderPlaced = false;

倘若使用者在「人才數量」欄位中輸入了一個數字,我們接著將這幾行加入isANumber()函數之中,把orderPlaced的數值改成「true」:

 
  if (answer == 1) {
    orderPlaced = true;
  }

我們以下面的方式來運用這個變數:

 
Total price
<INPUT TYPE="text" NAME="totalPrice" SIZE=10
  onChange="if (orderPlaced) {
    alert('Total fee is a calculated field.');
    calcTotal(this.value);
  }">

此處,要是使用者在提出有效訂單之後(orderPlaced已被設定為「true」),又試圖更改totalPrice欄位的數值,這時就會跳出一個警告訊息,通知使用者不可更動該欄位。除此之外,calcTotal()函數也會被再度叫出,以恢復totalPrice欄位中的數值。


現在,我們來弄點新奇的玩意好了。你可以運用JavaScript來判斷某個內容數值,是否與之前定義的模式相符(例如電子郵件信箱、社會保險號碼、日期、或是帳戶號碼)。我們將建立一個範例,好用來判斷某個數值看起來是否像是有效的電話號碼。但是,不論你想執行的是哪種模型,都可以運用類似的方法來進行。

一起將我們的新函數定義為isAPhoneNumber():

 
function isAPhoneNumber(entry) {
  //don't bother validating the pattern if
  //no value was passed in
  if (entry) {
    //parse the value into small subsections
    var openParen = entry.substring(0,1);
    var areaCode = entry.substring(1,4);
    var closeParen = entry.substring(4,5);
    var exchange = entry.substring(5,8);
    var dash = entry.substring(8,9);
    var line = entry.substring(9,13);

倘若你細分這一大堆的程式碼,那就很容易瞭解了。第一步,if(entry)檢查是否有輸入值存在。倘若有的話,程式碼會透過JavaScript的substring(),將輸入值細分成個別部份。substring()的方法相當有效,但是它並不怎麼直接。這個方法所傳回的字串部份(例如使用者所輸入的日期),是以你所給予的第一個參數作為開始,最後一個參數前一位的結尾數字作為結束。就像C語言一般,JavaScript將第一數字視為第零元件。因此,舉例來說,當你輸入"(123)456-7890",時,entry.substring(0,1)只會傳回第一個字,也就是"("; entry.substring(1,4) 則傳回"123"; entry.substring(4,5)則傳回")";,其它依此類推。

一旦我們將資料細分成合適的部份,就能按照我們的模式來檢查它們:

 
    //now check each of the subsections
    //individually
    if ((openParen != "(")
      || (!isANumber(areaCode,
"phone number - area code"))
      || (closeParen != ")")
      || (!isANumber(exchange,
"phone number - exchange"))
      || (dash != "-")
      || (!isANumber(line,
"phone number - line"))) {
        alert("Please enter phone number
in the following format: (123)456-7890");
    }
  }
}

第二步,if敘述檢查每一部份時,儘管只有一個部份不符合所預期的內容,但是整個電話號碼依舊被視為無效。以中文來說,上面的程式碼可以譯作下面的敘述:「假如openParen(或是areaCode《區域碼》不是數字,或closeParen看起來不像)或是電話號碼的交換部份,看起來不像數字,亦或是連字號(或電話號碼的排列部份)看起來不像數字,那麼請詢問使用者重新輸入電話號碼。」

透過將模式細分成不同的部份,我們就能分別檢驗每個部份。這可確實告訴使用者哪部份的數值有問題。將事情分開來進行,也有益於編寫程式:請注意,同一個isANumber()函數,在檢驗模式之中的每個數字部份時,都會被叫出來。

 


不同於欄位層級的有效性檢查,格式層級的有效性檢查,所檢視的是整個格式上的某群(或全部)數值的連續性。一般來說,進行格式層級有效性檢查的時刻,就是在傳遞已完成HTML格式至CGI程式之前。我們進行這項檢查,是為了確定使用者在傳送資料至伺服器之前,已經填好了每個指令欄。

確認整個格式真的非常簡單。在我們的例子當中,我們已經移除了大部份會自動跳出立即警告訊息的欄位層級有效性檢查。這裡就是一個範例:

 
function isANumber(number) {
  answer = 1;

  if (!parseFloat(number)) {
    //the first digit wasn't numeric
    answer = 0;
  } else {
    //the first digit was numeric, so check the rest
    for (var i=0; i<number.length; i++) {
      if ((number.charAt(i) != "0")
        && (!parseFloat(number.charAt(i)))) {
          answer = 0;
          break;
      }
    }
  }
  if (answer == 1) {
    orderPlaced = true;
  }
  return answer;
}

上面的程式碼,基本上是我們的數字檢查函數,不過缺少了JavaScript的警告訊息。在這個情況中,倘若使用者輸入了數字以外的字,我們不會自動送出錯誤訊息。

一旦使用者認為,她已經完成了整份格式,那麼就會按下「傳送」鈕。在那個時候,我們即會檢查每個欄位是否有遺漏、或是存有格式不正確的資料。

 
>function validateForm() {
  var fixThis = "";

  if
(!(isANumber(document.orderForm.numberOrdered.value))) {
    fixThis += "Please enter a numeric value
for the number of brains field.\n";
  }

  if
(!(exists(document.orderForm.typeField.value))) {
	fixThis += "Please enter the type.\n";
  }

  if
(!(exists(document.orderForm.stateField.value))) {
    fixThis += "Please enter the state.\n";
  }

  if
(!(isAPhoneNumber(document.orderForm.phoneNumber.value))) {
    fixThis += "Please enter the phone number
in the following format: (123)456-7890";
  }

  if
(fixThis != "") {
    alert(fixThis);
  } else {
    document.location.href = "thanks.html";
  }
}

這個函數的執行範圍,涵蓋格式中的所有欄位,它會檢查並確認每個欄位都包含有效的數值。倘若它發現某欄位缺少有效數值,即會在fixThis(修正這個)的變數上,添加一個新的警告訊息,然後再繼續下去。到了最後,它不是跳出一個含有各式各樣警告訊息的視窗,就是傳送一個簡短的「謝謝你」的訊息給使用者。


每位認真的網路族,都有碰到Image maps的經驗 -- 你知道,就是那些點選了不同地點,就會將你連至不同網址的圖片。JavaScript可讓你進一步延伸image maps。在我們的例子之中,當使用者點選了某位特定人才時,我們會給他們更多的資訊。

首先,我們簡單地設定一個函數,這個函數定義了image map兩邊的敘述內容:

 
function leftDescription() {

  //the "\n" character displays a line break
  document.orderForm.description.value =
"This is Lefty.  She enjoys figuring the tip
on \nrestaurant bills and sorting her 14 years'
worth \nof computer magazines by subject.";
}

function rightDescription() {

  document.orderForm.description.value =
"This is Righty.  He likes making sand
castles and \nsearching for connections
between old rock \nalbums and classic movies.";
}

上面的程式碼,比一開始看到的還要簡單。它定義了兩個函數,分別是leftDescription(),以及rightDescription()。當啟動這些函數之中的某一種時,相符的內容就會展示在稱為orderFormdescription敘述內容欄位之中。

我們現在要做的事,就是在使用者點選的時候,叫出JavaScript函數取代網址。我們將透過這樣來定義image maps的方式,來達成此目標:

 
<MAP NAME="brainMap">

<AREA NAME="leftHalf" COORDS="0,0,112,112"
HREF="javascript:leftDescription();">

<AREA NAME="rightHalf" COORDS="0,0,225,225"
HREF="javascript:rightDescription();">

</MAP>

在這個例子之中,當使用者點選了 image map 左邊的區塊,瀏覽器會啟動leftDescription()函數。同樣地,當使用者點選右邊區塊時,程式碼就會啟動JavaScript的rightDescription()函數。

此處要注意的是,倘若被叫出的函數,是位於HREF之中時,啟動的函數名稱就必須跟在javascript:字串之後(例如HREF="javascript:leftDescription()")。這樣可以讓瀏覽器瞭解到,接著將出現JavaScript的敘述。

現在,我們只需定義某些地方,來放置輸出的內容即可。

 
<IMG NAME="currentImage"
SRC="../../Images/java.window.gif" width=225
height=125 ALIGN="TOP" USEMAP="#brainMap">

<FORM NAME="orderForm">
<TEXTAREA NAME="description" COLS=40 ROWS=4>
</TEXTAREA>
</FORM>

這樣就大功告成了。我們已經運用HTML來告訴瀏覽器,要使用帶有java.window.gif的人才圖片。我們也定義了一個稱為orderForm的格式,並插入一個稱為description.的內容區。當我們點選此 image map 氶A相符的函數就會啟動,並以對該人才敘述來填滿內容區。

 


JavaScript能做的事,可不僅只有提供讀取HTML格式資料而已;它也能讓你建立自己的物件 -- 也就是讓你建立儲存在客戶端的資料。你甚至還能建立包含其它物件的物件。

為什麼需要這些功能?好理由之一就是建立 陣列。簡單來說,陣列是一個含有幾組相關資訊的表格或資料庫。在下面的例子當中,我們定義了一個稱為taxTable的物件,裡面含有五個名稱物件例子的陣列。這個陣列包括五個州的州名,以及它們的相關稅率。稍後,當使用者在訂購格式中輸入州名時,我們將會根據陣列來檢查,並自動應用合適的稅則。

建立一個5X2的陣列,與迅速做一個測試州名之用的if-then序列相比,似乎有點像是多餘的工作。不過,隨著輸入的數字增加,陣列也就變得愈來愈有效力。不妨想像一個擁有五十個州、或五百個銷售區、亦或是五千個城市的表格好了。有了陣列,你更能立刻建立輸入名單,每當使用者輸入新資料時,就可迅速加以引用。

這種特殊的JavaScript,起先就像我們的計算範例一般。不過這一次,我們並不止為了簡單的計算而已:

 
function state(stateName, stateTax){

  //fill the instance with the values passed in
  this.name=stateName;
  this.tax=stateTax;

  //then return the instance of state
  return this;
}

上面所定義的state(),建立了包括名稱與稅率的州例子(state instance)。然而,我們的州此時似乎什麼數值都沒有。讓我們輸入一點數字吧。

 
function taxTable(){

  //the instance of taxTable is filled with
  //an array of state objects
  this[0]=new state("AZ", 0.04);
  this[1]=new state("HI", 0.10);
  this[2]=new state("TX", 0.06);
  this[3]=new state("NJ", 0.08);
  this[4]=new state("", 0.00);

  //return the newly created taxTable to
  //the calling function
  return this;
}

現在,無論taxTable函數何時被叫出,我們都建立了五種不同的州例子,分別編號為0到4。這樣一來,我們就做好了一個陣列,此陣列擁有我們所有的稅率資料。現在我們需要加以處理一番:

 
function calculateTax(stateValue){

  var index=0;
  var result=0;
  var temp=0;

首先,我們定義一個稱為calculateTax.的函數。calculateTax會以某些變數作為開始。然後,它需要從使用者那裡取得一個數值:

 
  //while there's an instance of state
  //in the taxGuide array
  while (taxGuide[index]) {
    //if the state passed in is in the
    //taxGuide array
    if (stateValue.toUpperCase() ==
taxGuide[index].name) {
      // put the correct tax rate in "result"
      result = taxGuide[index].tax;
    }
    index++;
  }

迴圈會繼續將使用者的輸入,與稅金表格中的所有可能輸入相比對,直到執行完全部的資料為止。一旦它發現相符的一組(或是沒有相符的情形)時,它就會在結果變數中,輸入合適的稅率。我們接著即可運用該稅率,來計算全部的金額,然後將其加至我們的總額之中。

 
  calcTotal();

  var temp1 = document.orderForm.totalPrice.value;
  // calculate total with tax
  var temp2 =
(parseFloat(temp1) * (1 + parseFloat(result)));
  // chop off extra decimal places
  var totalWithTax =
(Math.round(temp2 * 100)) / 100;
  // change value in form
  document.orderForm.totalPrice.value =
totalWithTax;
}

上面的程式碼,計算了包括稅金在內的全部費用。首先,我們設定temp1變數等於totalPrice格式元件的數值。接著,我們再計算包含稅金在內的總額,將其設定為「temp2」。下面一行則運用Math.round方法,來捨去額外的小數位,並將新的總額指定為totalWithTax變數。接下來,我們將此總額送回訂購格式之中。