當瀏覽器讀入一頁網頁時,就會根據此網頁的內容來建立相關的文件物件模型(Document Object Model,簡稱 DOM),這是一個階層式的物件模型,包含了網頁的各種物件,我們需要瞭解這些物件的性質和方法,才能產生動態的網頁,充分利用動態 HTML(Dynamical HTML,簡稱 DHTML)的各種功能。
在文件物件模型中,所有的物件之間的關係,是由一個階層式的樹狀架構來呈現,請見下圖:
由上圖可以看出,window 物件是所有物件的始祖。而由每個物件的分支多寡,就可以大概看出此物件的重要性,例如, window 其下最重要的物件是 document,而 document 其下最重要的物件是 form。
這些物件各有不同的性質 (Properties) 及方法 (Methods),JavaScript 可利用這些性質及方法來建立網頁的互動性。
首先我們必須知道如何取得物件的性質,並進而改變這些性質,才能產生動態網頁。欲存取物件的性質,有下列三種方法:
- 用性質名稱來存取物件的性質(這是最常用到的方法):
objectName.propertyName
- 用性質名稱來存取物件的性質(此種方法同等於前一種方法,其好處是:可將性質名稱以字串變數傳入):
objectName["propertyName"]
- 用索引來存取物件的性質(比較少用):
objectName[index]
首先,我們先看看 window 物件幾個常用的性質,利用這些性質,我們可以立刻抓出目前網頁的網址,以及視窗的座標等資訊,範例如下:
上述範例的原始檔如下:
你可以移動本範例的視窗,然後在更新此網頁,就會看到不同的 X 和 Y 座標值。
下一個範例,我們說明如何經由 window 物件的性質來修改視窗的狀態列(Status Line)。一般而言,狀態列是在瀏覽器視窗的最下方,在預設的情況下,當你將滑鼠置於網頁中的一個連結時,瀏覽器就會在狀態列秀出此連結的網址。欲改變瀏覽器狀態列的文字,可將文字指定至下列兩個性質:
- window.defaultstatus:狀態列的一般預設文字
- window.status:在特殊事件被觸發後,狀態列所顯示的文字
請見下列範例:
在上述範例中,我們將瀏覽器視窗的預設狀態列改成「這是我的預設狀態訊息」,但是當使用者將滑鼠放在「清華大學」時,狀態列的訊息則會改為「清華大學的首頁」,而不會像一般瀏覽器出現清大首頁的網址,這是因為我們使用 onMouseOver 事件(當滑鼠置於連結時)來觸發一段 JavaScript 的程式碼,並進而改變 window.status。特別要注意的是:此段程式碼必須回傳 true,否則 window.status 的改變將不會發生,請見上述範例的原始檔:
在 window 物件之下,最重要的物件就是 document,有關於 document 物件的幾個常用到的性質,請見下列範例:
上述範例的主網頁原始檔如下:
上述範例中,最常用的性質就是 document.lastModified,可以傳回網頁最後修改時間,讓其他使用者知道此網頁的有效性。
此外,一個常見的應用,就是要防止其他網頁的盜連,所使用的 document 的性質是:
- document.location:本頁的網址(可以修改以進行轉址)
- document.referrer:連結到本頁的前一頁網址
範例如下:
在上述範例中,如果我們直接從「主網頁」點選「被保護的網頁」,則可以直接顯示「被保護的網頁」。但是如果我們直接將「被保護的網頁」的網址貼在瀏覽器的網址列(或點選其它網頁中含有「被保護的網頁」的連結),JavaScript 可由 document.referrer 偵測這種「盜連」的情況,因此不會顯示「被保護的網頁」,而會直接轉址到「主網頁」。採用這種機制,可以確保自己的底層網頁內容不會被「盜連」,而一定要從主網頁進入。上述範例的原始檔如下:
被保護之網頁的原始檔如下:
如果我們將被保護之網頁網址直接貼到瀏覽器的網址列,瀏覽器會經由 document.referrer 來判斷是否合格,並進行必要之轉址。
若要測試客戶端所用的瀏覽器,可以使用 navigator 物件的各種性質,範例如下:
上述範例的原始檔如下:
換句話說,我們只要使用 navigator 物件的各種性質,就可以知道使用者的瀏覽器類別、版本、CPU 類別、平台、是否支援小餅乾之類的資訊,對於我們撰寫跨平台的 JavaScript 程式碼非常有用。
看了上面的範例,各位讀者一定有一個疑問:一個物件到底有什麼性質呢?還有這些性質代表什麼意義呢?事實上,隨著瀏覽器的演進,每一個物件所包含的性質是越來越多,因此若能直接由 JavaScript 來列出網頁文件中的物件所具有的性質,那就再好不過了!我們這裡有個 JavaScript 的函數 listProp(obj, objName),可以列出一個物件的所有性質,其原始碼如下:
在上述程式碼中,obj 是傳入函數的物件變數,objName 則是物件名稱,局部變數 i 則會依次等於物件的每一個性質名稱,obj[i] 則是對應性質的值,我們再用 document.writeln 的方法來將這些資訊印出至網頁。
舉例來說,若要列出 document 物件所具有的性質,可利用 listProp.js 的函數,範例如下:
上述範例的完整原始檔案如下:
由此範例可見 document 物件有許多性質,這些性質都可由上述方法逐一列出。若出現的性質是 [object],代表此性質是另一個物件,因此我們可以再次列出此物件的性質,例如,document.links 是另一個物件,代表此文件中所含的連結,因此我們可以再次利用 lispProp.js,印出 document.links 的所有性質,如下:
上述範例的完整原始檔案如下:
同理,我們可以對 window 或是 navigator 物件的性質進行完整的列表,相關範例可見本書之範例光碟:
我們也可以使用 DOM 的各種物件與方法來立即切換音樂(包含 MIDI、MP3 和 wma 音樂)與圖片,請見下列範例:
你可以點選「換背景圖片」來由亂數選取背景,也可以點選「換背景音樂」來由亂數選取背景音樂。上述範例的原始檔如下:
本範例的相關技術重點,說明如下:
- 若要設定背景圖片,可經由 document.body.background 來設定背景圖片的網址。
- 我們可以使用 bgsound 標籤來加入背景音樂,並設定此物件的 id 屬性是 myMusic,然後再經由 myMusic.src 來設定背景音樂的網址。
一般而言,每一個 HTML 的標籤就是一個物件,我們可以使用 id 標籤來存取此物件,例如設定 id=idValue。一般而言,如果此標籤是在 document 的下一層(或是位於 <body> 及 </body> 內且不被其他標籤所包夾),則我們可以直接使用此 idValue 來存取此物件,例如上述範例的 myMusic.src。但是,如果標籤是在層層 DOM 之下(例如表單內的文字欄位),那麼直接使用 idValue 是無效的,此時只要 idValue 在整個網頁是唯一的,我們可以使用兩種方法來取得此物件:
- document.getElementById(idValue):這是標準的作法,符合 W3C 的標準。
- document.all(idValue):這是 IE4 自創的規格,目前並未被 W3C 的標準 DOM 所採納,但是目前似乎連 Firefox 都已經實做了這項性質。不過為了保持跨瀏覽器的相容性,最好還是使用 document.getElementById。
當然,對於每一個標籤,我們還是可以使用 name 標籤來指定此物件,但取用比較麻煩,必須從 document 開始抓取,例如如果一個文字欄位(name=myText)位於一個表單(name=myForm),那麼此文字欄位所對應的物件就是 document.myForm.myText.
JavaScript 程式設計與應用:用於網頁用戶端