實戰Dynamic HTML網站技術

本書基本資料
回上頁
書名：實戰Dynamic HTML網站技術
出版日期：1999/11/01
書號：957-8239-83-1
ISBN：957-8239-83-1
原作者：Eric M.Schurman William J.Pardi
譯者：成東陞
書本簡介
本書各章節
譯者序
本書介紹

Part 1 Dynamic HTML：互動網頁內容的架構
1.動態網頁(Dynamic HTML) 概論
. 何謂動態網頁 (Dynamic HTML)?
. 誰應該使用動態網頁?
. 我們開始吧!
2.HTML基本觀念
. 基本標籤(Tag Basics)
. 建立清單 (Constructing Lists)
3.表格及框架
. 表格
. 框架
4.表單、實用的HTML標籤、及字元的代碼
. 表單
. 其他有用的HTML標籤
. 字元的原形
5.動態網頁物件模型
. 動態網頁物件模型的基本原則
. 動態網頁模型的基本元件

Part 2 加入互動性: 使用腳本語言讓您的網頁動起來
6.Script腳本語言簡介
. 在Internet Explorer中可使用Script語言
. Script語言的功能
. HTML中的Script
. 將Script加入網頁中
7.物件導向式的Scripting技術
. 物件值得注意的地方
. 讀取和改變屬性
. 捕捉事件
. 呼叫方法
. 使用集合
8.資料處理
. 變數
. 資料類型
. 變數與資料處理
9.函式、條件式與迴圈
. 函式
. 條件式
. 迴圈
10.除錯與錯誤處理
. 錯誤的種類
. 除錯(Debugging)

Part 3 文字與網頁版面配置: 使用串接式樣式表
11.CSS簡介
. 行內樣式
. 樣式表
. 集體設定與屬性速記
. 繼承特性
. 類別 (Class)
. 鏈結 (Links)
. 串接樣式
. 動態樣式(Dynamic Styles)
12.控制字體與文字樣式
. 文字有關的屬性
. 文字的屬性
. 度量單位(Units of Measurement)嵌入字型(Font Embedding)
13.利用樣式表來控制版面與位置
. 格式化元件
. 網頁的版面配置
14.用CSS來控制其他瀏覽器元件
. 利用CSS來控制表格
. 利用CSS來控制指標
. 使用CSS來控制列印
. 使用CSS來控制清單
15.動態樣式腳本語言設計
. CSS和動態HTML物件模型
. 使用Script來讀取及設定CSS屬性
. 建立可摺疊式大綱項目
. 在螢幕上產生移動效果
16.視覺特效濾鏡以及轉換特效
. 概論
. 濾鏡
. 轉換特效
. 將特效結合

Part 4 多媒體
17.網頁上的多媒體效果
. 概論
. 撥放多媒體
. 串流式撥放媒體
. 動態GIF檔
. 如何規劃多媒體網頁
. 建立網頁使用的聲音及影像檔
18.有關聲音與影像的進階技巧
. <BGSOUND> 標籤
. <IMG> 標籤以及DYNSRC屬性
. 利用媒體控制項在網頁上加入影像
19.DirectAnimation多媒體控制項
. Structured Graphics控制項
. Sequencer控制項
. Path控制項
. Sprite控制項

Part 5 進階技巧：資料連結、XML及其它技術
20.資料連結 (Data Binding)
. Data binding的優點
. 資料來源物件(DSO)
. 表格資料控制項(Tabular Data Control)
. 額外取得資料的方法
. 額外使用Data binding的方法
21.延伸式標示語言XML
. XML的背景
. XML是一種資料
. XML和Internet Explorer
. 基礎之外的其它Scripting技術
. XML Data Island
22.額外新技術
. 使用ActiveX控制項
. Scriptlet
. Behavior
. Cookie
. HTML Applications
. 建立頻道 (Channels)
. 設定分級系統
23.跨瀏覽器和平台的網頁
. 瀏覽器的常見問題
. 建立跨瀏覽器的網頁內容
. 共同的問題
24.整合Web程式設計技巧
. 網站的功能
. 網站所包含的檔案
Appendix A 解決一些疑難雜症
Appendix B 好用的工具和資源
Appendix C Dynamic HTML物件模型之組成元件
Appendix D 前256個字元代碼


實戰Dynamic HTML網站技術=>譯者序

實戰Dynamic HTML網站技術 視窗縮放
譯者序
小
工
具 加入書架
加入書籤
上一章
下一章

隨著World Wide Web及Internet 的快速成長，許多令人稱奇的網頁設計技術也紛紛出籠，例如: 動態改變內容的網頁、互動式網站、物件化網頁、版面樣式與內容分離概念、多媒體網站、資料庫網站、跨瀏覽器網頁、利用標準資料交換格式傳遞資料、Windows DNA 3-tier Web資料庫應用程式...等等，這些特殊的網頁設計方式在前幾年可能還是天方夜譚，不過現在只需利用動態網頁 (Dynamic HTML) 的技術即可輕易完成。其實Dynamic HTML也是目前在網頁設計與網路傳輸上最有效率的開發方式，符合TCO (Total Cost Ownership) 的觀念。

本書涵蓋幾乎所有的Dynamic HTML的主題，例如：Scripting技術、文件物件模型 (Document Object Model ; DOM)、串接式樣式表 (Cascading Style Sheets ; CSS)、動態樣式 (Dynamic Styles)、多媒體濾鏡 (Filters amd Transition)、JScript錯誤處理 (Error Handling)、保存技術(Persistence)、Cookies、建立跨瀏覽器 (Cross-browser)的網頁、網頁資料連結技術 (Data Binding) 之TDC/RDS/JDBC ... 等。此外，對於一些新技術，例如：XML、Scriptlet 、HTAs (HTML Applications)、DHTML Behaviors本書也有介紹，並附上實際例子供您參考。因此讀完本書後，想要建構一個全功能的動態網站非夢事。

近來提出的XHTML、CSS3草案等新規格標準，相信又會將原本已十分豐富的動態網頁設計帶入另一高峰，因此不論您有興趣的是建置個人網頁或功能強大的資料庫系統網站，動態網頁的開發相信都是一個有趣且值得努力的領域。

最後特別感謝1 范史惕 、 何凡齊 二君於百忙之中，抽空審稿。此二君於網頁技術領域學有專精，沒有他們的幫忙，本書不可能完成，特此感謝。

成東陞1999.10

實戰Dynamic HTML網站技術 視窗縮放
譯者序


實戰Dynamic HTML網站技術=>本書介紹

本書介紹
小
工
具 加入書架
加入書籤
上一章
下一章

當我們在利用前版的Internet Explorer 4瀏覽器來開發應用程式時，我們沒有任何資源或途徑可以展示各種網頁的新技術，所以在本書中將包含了我們經由在Internet Explorer或Netscape Navigator上開發各種網站的經驗。

網站開發除了要瞭解不同瀏覽器如何運作外，也需要了解一些技術，這包括HTML，腳本語言(Script)，串接式樣式表(Cascading Style Sheets;CSS)，多媒體及一些其它進階的技術。本書的目的就是要幫助您更快速有效的建立跨瀏覽器的網站。

您應該要知道

這本書是針對於有電腦基本觀念及對於WWW和Web瀏覽器有些熟悉度的讀者。如果您是下列任一種人員，您將會對於本書有興趣：1

  • 一個熟悉Web且很想開始建立簡單的HTML文件之初學者。
  • 一個網頁開發者想要增進Scripting和DHTML的知識。
  • 一個有經驗的程式設計師想要踏足網際網路的技術。

雖然有程式基礎可讓有關腳本語言 (scripting) 的主題更容易瞭解，不過閱讀本書並不需要任何程式設計經驗。此外，雖然我們會在前面幾個章節講述一些基本的HTML觀念，不過先認識一些HTML也是有幫助的。

本書包括許多範例程式，以文字檔的形式儲存在隨書光碟中。您可以計劃將這些範例當作範本來使用，或如果您在一個特定問題上遇到瓶頸時，也可以將範例當作一個靈感的來源。您甚至可以複製這些範例並運用在您的網站上。

網站連結

本書大部分的章節都包括許多不同可供參考的網頁位置。雖然在本書寫作時每個網站連結都十分正確且皆可正常連結，不過請注意Web網站都會時常更新，所以當您試著要連接至本書所提到的某網站時，該網站可能已經無法正常連結。為了減少這個問題，我們建立一個經常更新的網站，此網站包含了許多確定可以連上的線上連結。您可以在MSDN線上資源網站找到這個網頁，網址為2 msdn.microsoft.com/resources/schumandhtml.html ，或您開啟隨書光碟檔名MSDN_OL.htm的網頁。

本書從頭到尾，我們都有參考Microsoft Site Builder(SBN) 網站中的資料。大多數的這些資源可以從隨書光碟或網站上取得。若要從光碟讀取某個主題的資料，可開啟Workshop(References).htm，然後依照指示瀏覽到您要的特定主題，這些主題也可直接上網站查詢。若想要取得線上版本，可連上剛剛所提到的MSDN線上資源網站，或連上 microsoft.com/sitebuilder 。

本書的組織架構

本書的架構分成幾個部分，我們從最基本的網頁開發基礎觀念與技術開始講起，隨著本書進行，會從這些基礎開始，到涵蓋可讓您對於瀏覽器做更複雜控制的技術。在本書最後的部分講述到某個特定瀏覽器的一些技術，或一些較為技術的特性。3

第一部份 Dynamic HTML：互動網頁內容的架構

在第一部份的章節中，可以概括的了解動態網頁可以做些什麼，此外也介紹了HTML，和可以控制網頁在瀏覽器中顯示的基本標準。在這個部分，我們涵括了如何格式化文字來建立表格或複雜的表單，第一部分的最後一章介紹了物件模型(Object Model) 的觀念，而它是用來透過腳本語言(script)來處理網頁內容的。

第二部份 加入互動性：使用腳本語言讓您的網頁動起來

在第二部分，我們討論腳本語言(Scripts)，腳本可以讓您在瀏覽器中進行可程式化的工作，在本書，我們將焦點放在JScript和JavaScript (同一個scripting標準，但分別是Microsoft和Netscape的不同實際版本)，因為它們都廣泛的被使用。

此部份的章節涵蓋主題範圍，從資料類型，函式，條件式，錯誤處理，到物件模型的應用。

第三部份 文字與網頁版面配置：使用串接式樣式表

第三部分涵蓋了串接式樣式表的使用，這是一個可以將文件內容與樣式分離的標準，而且它可以同時提供對於網頁外觀良好簡便的控制。本部分也討論了如何利用script來處理CSS，此外也講述了視覺濾鏡和轉換濾鏡。4

第四部份 多媒體

第四部分將教您如何在網頁上使用多媒體. 討論的主題範圍從影像和聲音到DirectAnimation多媒體控制，它提供了如此有用的功能，例如精確的事件，物件移動及向量圖形的時間控制。第四部分也討論了想要成功地在網站上完成多媒體功能，會遇到的一些困難。

第五部份 進階技巧：資料連結、XML及其它技術

第五部分的章節涵蓋了很廣且很多的主題，範圍從DHTML Behaviors和cookies到網頁的資料整合。在這個部分有一整章講述建立跨瀏覽器的網頁內容會遇到什麼挑戰。最後一章將很多本書討論的技巧集合起來放到一個範例網站上。

附錄

最後的四個附錄討論錯誤處理，列出一些有用的工具和資源，提供物件模型文件，且提供有用的字元實體參考列表。

本書光碟包含了哪些東西?5

在本書後面，您可以發現附了一個隨書光碟，它包含了：

  • 一個readme.txt檔案，它說明如何安裝和使用光碟中的各項元件。
  • 本書所有的範例檔，以章節名稱來編排。
  • 一個範例網站，執行SampSite.htm就可以開啟這個網站。
  • 一個HTML格式的本書電子版本，在Ebook資料夾中。
  • 一個縮小版的SBN Workshop網站，包含許多參考範例。
  • JScript和VBScript的完整文件，放置在Tools目錄中。6
  • tools目錄中的各式各樣工具。
實戰Dynamic HTML網站技術 視窗縮放
本書介紹


實戰Dynamic HTML網站技術=>動態網頁(Dynamic HTML)概論

動態網頁(Dynamic HTML)概論
小
工
具 加入書架
加入書籤
上一章
下一章

若您隨著這幾年全球資訊網 (WWW或web) 的發展一同走來，或許常聽到 "網際網路時代" 這個名詞。由於Internet與Web以不可思議的速度成長，已經促使很多新的企業，都紛紛在Internet或Web上開發新的應用程式 (applications或簡稱apps)。為了與下一代Web應用程式的競爭對手比賽，各家公司都以空前的速度發展新的軟體。在這種情形下，真正的"網際網路時代" 也許會更早來臨。

這種爆炸性的成長速度，在瀏覽器的領域中情況最明顯。第一代的瀏覽器曾只能顯示基本的文字與圖案，不過，隨著時間與科技的向前邁進，瀏覽器的功能變得更複雜。最顯著的進步就是諸如：新增物件模型 (Object Model)、支援script腳本語言功能、對於網頁外觀有更好的控制能力，及可在客戶端 (clInternet Explorernt-side) 即時動態地處理網頁的能力。

本書的範圍包含了Microsoft Internet Explorer和Netscape Navigator兩種瀏覽器。不過，在本書結尾的一些章節中所討論的技術，就只能使用在Internet Explorer中。我們會說明如何利用Netscape Navigator來處理這些技術，以及提供替代方案的方式。但在本書仍會比較兩種瀏覽器之間不同的地方。而在第24章中，我們將討論如何設計出兩種瀏覽器都能使用的網頁。

Note

大部分瀏覽器和其他網頁相關技術的標準，都是由全球資訊網協會(World Wide Web Consortium;W3C) 所發展出來的，這是一個在1994年所成立，獨立制定標準的團體。W3C的目標是 "發掘Web所有的潛能"。想要清楚更多有關W3C的資料與其相關工作範圍，請連上W3C Web網站1 http://www.w3.org/ 。

何謂動態網頁 (Dynamic HTML)?

若從字面來看動態網頁這個名詞，常會產生一些誤解。因為動態網頁 (Dynamic HTML;DHTML) 不只是一個特定的技術、語言或一組功能元件。相反的，動態網頁是由不同的技術所組成。而且使用的重點，在於描述網頁中的各式元件與技術如何互動。簡單來說，動態網頁中可以使用：傳統的HTML、腳本語言 (script)、文件物件模型 (Document Object Model)、絕對定位(absolute positioning)、動態樣式 (Dynamic Styles)、多媒體濾鏡 (Multimedia Filters)...等等，和各式各樣的其他技術組合。而這些技術，可以大幅改變在螢幕上顯示的文字與圖形外觀。

讓HTML動起來

毫無疑問的，HTML仍是Web上最重要的網頁技術。自1990年代中期HTML開始被廣泛使用後，HTML已經過不斷的發展，並增加了許多新的功能。(本書的第一篇將會詳細講述HTML)。

但除了一些例外 (例如：當使用一些特殊的ActiveX控制項，或改變表單欄位)，HTML網頁通常是靜態。HTML改變螢幕內容的唯一方式，通常就是再載入另一個網頁。2

然而Internet Explorer 4.0和5.0版本，支援使用文件物件模型 (Document Object Model) 的延伸功能，它可以對頁面上的元件做進一步的控制，其中更包括了原本的HTML元件。即使網頁已經完全被載入，並進一步變成固定格式，它仍可以在任何時刻改變在Internet Explorer中的HTML元件，將原有的靜態HTML變成會變動的HTML文件。雖然Netscape也可以允許設計者，做某些程度的物件操作。不過，Netscape的物件模型不像Internet Explorer那樣完整，但兩個瀏覽器都是利用腳本script來完成元件的控制操作。

利用腳本 (Scripts) 來整合網頁

您不需撰寫一行script程式碼，也可以做出許多不同的網頁設計。但若要真正使用到瀏覽器的優點並善用其功能，您也許需要學一些Scripting技術。但我們必須警告，你可能用過script之後，就可能會養成用script的習慣(habits-forming)。一旦您知道script是如何有效的改變你的網頁外觀，您可能以後會受不了不加Script的一般網頁! 很多沒有程式經驗的網頁設計者，都覺得script太難、不好學或難用。而我們也同意scripting好像有點複雜。但我們將會做一些示範，如何利用很簡單的script，就能發揮瀏覽器強大的功能。

舉例來說，若有一個包含圖形的網頁。

若只是使用HTML來改變圖片，唯一的選擇就是開另外一個網頁，再顯示一個新的圖片。使用Dynamic HTML，您只需改變HTML圖片標籤的屬性就可以改變圖片了。所以我們可做出一個新網頁，只要在燈泡圖片上面按一下鈕即可以將燈泡變亮（結果請開啟書附光碟的chap01\bulbtest.htm網頁）。

3

注意圖形並沒有重新整理網頁就能改變了。這個例子只使用了Dynamic HTML和一些簡單的script。中間並沒有新的標籤，沒有Java程式碼，也沒有ActiveX控制項。裡面只有HTML，和一點點script。

Scripting技術，在Internet Explorer 4.0版以後的瀏覽器中特別重要。在前幾版中，您也可以使用scripting來叫用這種物件或元件，不過能叫用物件種類非常少。在4.0及以後的版本中，更多的元件被當成物件，因此可以利用script來叫用。JavaScript的相容語言 (就如Microsoft的JScript和Netscape的JavaScript) 和Microsoft的Visual Basic Scripting Edition (VBScript) 是兩種在網頁上常見的scripting語言。某些伺服器上，也支援這兩種語言。script通常都嵌入在網頁HTML中，跟著網頁一起被下載。您也可將script分離成一個獨立的檔案，然後在需要的時候，允許這些script被某個網頁所執行或重新使用，這種script可與不同網頁連結使用。（在本書第二部份中，我們將提供對於scripting做更深入的說明，並會針對Microsoft的標準scripting語言 "JScript" 做詳細的探討)。

利用串接式樣式表來控制網頁版面配置

以往所謂的網頁 "出版" (Publishing)，就只是單純的將網頁放到網站上。但是，您會發現在版面配置上，網頁出版與一般的紙上的文件不太相同。網頁的版面配置，或在Web的詞彙來說，網頁的 "外觀" (look and feel) 一直都只能在有限的範圍內發揮。但現在的瀏覽器，可以讓作者和設計者更進一步控制網頁元件的外觀及行為 ，特別是出現在螢幕的文字。從Internet explorer 3與Netscape Navigator 4開始提出了串接式樣式表 (Cascading Style Sheets；CSS) 技術，讓網頁的版面控制更具彈性。Microsoft實作CSS的方式，就是透過動態樣式 (Dynamic Styles)。樣式表能讓網頁開發人員，對於版面設定與格式擁有更多的控制能力，它包括有：

  • 字型 (Fonts)
  • 顏色 (Colors)
  • 邊框 (Borders)4
  • 背景 (Backgrounds)
  • 放置位置 (Alignment)
  • 絕對位置 (Absolute position)
  • 行距 (Leading "line spacing")
  • 濾鏡效果 (例如向下陰影 (drop shadow) 和火焰 (glow)，只可用於Internet Explorer)

圖1-1是一個設定文字格式的例子，可用一般的HTML設計出來。雖然你還是可以做一些控制，不過跟動態樣式相比，還是十分受到限制。如圖1-2所示，透過動態樣式，您可在網頁的元件上利用絕對定位功能，還可外加濾鏡並改變字元間距 (您可以在光碟中的chap01\ styles.htm中，找到這個範例的HTML原始碼)。動態樣式也能讓網頁內容開發者，在網頁載入後，再改變元素的樣式屬性。這種功能，能讓您建立一些特殊效果，例如：捲簾式清單和網頁上移動的物件。

幸運的是，CSS不只對文字有效，您也可在其他物件上應用樣式屬性，從表格的邊框型式到是否顯示圖型... 等等。本書第三部份中，將詳細討論如何使用CSS來設定文字與網頁配置。5

圖1-1　利用HTML格式化文字

圖1-2 　使用串接式樣式表的動態樣式

在Internet上使用多媒體資源

在網頁上顯示多媒體元件，對於瀏覽器來說並不是最新的功能；在先前的版本中，可能只可使用ActiveX控制項、Java applets、基本內建工具、或特殊的plug-ins ...，來展示網頁多媒體的效果。但Microsoft在Internet Explorer 4和Internet Explorer 5中，改善了網頁多媒體的功能。因為瀏覽器軟體本身，就包含了許多不同的控制項，或是可以自動下載這些控制項。高品質的多媒體效果，通常都需要這些控制項的協助。本書的第四部份，將會討論各種跨瀏覽器 (cross-browser) 以及Internet Explorer特定的多媒體效果。以下列出最新版本瀏覽器中能找到的多媒體元件，以及它們的用途：

  • 媒體播放程式6 這個媒體控制項能讓您在網頁上，加入聲音、影像，ASF (Advanced Streaming Format) 格式的影像與聲音串流...等多媒體特效。它提供了錄影機式的控制面板及功能，包括有播放、停止、和暫停。然而不論內建的控制工具列是否顯示，都可以播放多媒體特效。
  • 串接式樣式表濾鏡與轉換濾鏡 雖然CSS常常只套用在文字上，但是多媒體濾鏡與轉換濾鏡卻也是動態樣式的一部份。你可以將它應用到許多型態的物件上，包括圖像、影像及甚至網頁本身。有關CSS的使用方式，請參閱第三部份的說明。
  • 結構化圖形控制項 您可以利用這個控制項，建立複雜、小型的、及可縮放的向量圖形。這些圖形增加的檔案大小有限，且可以在3-D空間中旋轉，提供頗酷的網頁特效，使用的頻寬也非常少。
  • Sequencer控制項 您可以利用連續畫面控制項來加入精確的時間安排和小型的動畫效果。您可透過script來控制網頁上各種不同事件發生的時間。7
  • Path控制項 您能利用這個控制項，來控制網頁上元件的移動路徑。路徑可以是簡單的一條直線，或是複雜的的圖案。將路徑控制項與其他多媒體控制項結合，可以產生一些令人印象深刻的效果，而且下載時間也不會花很久。
  • Sprite控制項 這個控制項允許您控制 (frame-level control) 圖像的每一格畫面,如此便可在網頁上建立動畫，框格 (Frames) 可以是獨立的圖片或是一段影像圖片。也就是說，這個控制項可以處理影像檔案的一部份。

您可以在本書第四部份中，找到更詳細的討論內容。

上面的說明重點在於：多媒體元件可以利用script來做控制。所有運用在網頁上的多媒體效果，可以使用HTML和script來做控制與播放，這也是在Internet上播放多媒體的關鍵。當多媒體效果的資訊都來自HTML和script時，這些網頁通常都會非常小，而且下載也非常快速。

額外的技術8

許多其他很酷的技術，現在都能使用到網頁上了，範圍從Scriptlet Behavior，到資料連結 (Data binding) 和XML (延伸式標示語言)。本書的第五部份將深入探討這些技術和其他有用的主題，例如讓您的網頁能在不同版本，且不同特性的瀏覽器中使用的技巧。我們先來快速瀏覽一下其中一個技術：資料連結(Data Binding)。在動態網頁出現之前，若想要將資料顯示在網頁上必須靠伺服器端將資料送到網頁上，且還是靜態資料。舉例來說，假定您看到一個網站，它以每個樹的型態和平均高度來顯示以樹狀結構為基礎的資訊，如下所示：

若只想看中等高度的樹資料，您可以從Sort By列視窗中選擇關鍵字Medium然後傳送要求。伺服器將會收到請求，然後做一些資料的處理，然後傳回中等高度的那一列樹資料到網頁上。若您接著只想要看deciduous型態的樹資料，您需要傳一個新的詢問回去伺服器。伺服器接著又會處理這個詢問，然後傳回一組新的結果。伺服器當您每次要檢視新資訊時，就要提供一次服務。

然而Internet Explorer 4及更新版本，支援資料連結 (Data Binding) 技術，可以減少一大堆這種伺服器來往傳輸。資料連結能讓網頁設計者及開發者，直接將資料連結到網頁上。使用者不需要將要求傳回到伺服器，就可以修改網頁上的檢視內容。對於一個使用者來說，只要對伺服器傳一個要求，就可以接到所有樹的資訊。同時可以按照您的意思，使用不同的排序或篩選方式。舉例來說，下圖中展示了篩選中等高度樹的資料結果。

想要看這個展示例子，開啟書附光碟的chap01\treedemo.htm。注意雖然您可以用許多不同方式檢視資料，但是網頁其實只下載一次而已，在第五部份中我們將會詳細介紹資料連結。

誰應該使用動態網頁?9

若您要在Internet和Intranet或甚至在CD-ROM進行出版工作－換句話說，若您是一個網頁內容開發者，或是一個內容提供者，利用Dynamic HTML可以得到許多好處。當然，網頁內容開發者和網頁內容提供者只是一個代名詞，它可能指的是任何人。當您符合下列條件之一時，就適合使用Dynamic HTML：

  • 想要建立真正酷的專業網頁或個人網頁。
  • 不想使用專業多媒體工具，但想要透過瀏覽器來呈現內容的多媒體開發者。
  • 要使用複雜的動態網頁，來增強公司的網站功能的網站管理者。
  • 想要整合Internet技術到C++ 或Java的程式開發者。
  • 觀察到Intranet技術，能取代一些它們目前高花費、需要費力維護、分散式的應用程式的網路管理者或MIS經理。
  • 一個想要使用Intranet技術加到它們公司的小型企業老闆。10

不論您是否已經擁有自己的網頁，或是第一次接觸Web技術，Dynamic HTML都適合您。

一些動態網頁的另類使用方法

多數人將動態網頁，單純當作是一種網頁內容的傳送技術，然而它還有許多應用方式。舉例來說，我們已經看到DHTML被使用在應用程式、多媒體的CD教學軟體、複雜之分享應用程式的help文件。因為Internet Explorer具有實用性與彈性的：所以除了網頁瀏覽器之外，它還可以當作一個顯示引擎，更可以當作其他應用程式的物件一樣被控制。舉例來說，您可以使用Internet Explorer來建立一個CD-ROM的多媒體光碟、或是設計它成為一個HTML編輯程式的預覽平台、或將C++ 與HTML混合撰寫一個應用程式使用者介面。不過，如何完成這些工作已經超出本書所講述的範圍；然而您仍可以從Web開發者重要的資源網頁SBN(Site Builder Network)，找到很多實用的資訊。例如：可下載的工具和範例、最新建置網頁技術的文件，和線上專家及其訓練課程。SBN的一個重要的網頁就是SBN Workshop，它包括很多資料，和對於各種主題的參考資訊。其中包括有HTML所支援的屬性表，和詳細有關網站設計與XML的資訊。書附光碟包含一個SBN的快速瀏覽網頁。若想連至線上版本的Workshop網頁，請連到 microsoft.com/workshop/default.asp

我們開始吧!

現在您準備好要深入這些課題嗎? 請捲起您的衣袖，實際動手做吧! 由於本書其他部分將會教您如何使用Dynamic HTML，所以您將會很快做到本來曾經覺得在網頁上不可以做到的功能。本篇接下來將會探討如何使用基本的HTML，來建立您自己的網頁。

實戰Dynamic HTML網站技術 視窗縮放


實戰Dynamic HTML網站技術=>HTML 基本觀念

HTML 基本觀念
小
工
具 加入書架
加入書籤
上一章
下一章

因為HTML (Hypertext Markup Language，HTML) 還是用來控制瀏覽器顯示內容的主要技術。所以在了解其他的網頁技術前，您會發現若不了解HTML，是無法設計出動態網頁的。

科學家原先設計HTML的目的，只是為了建立以一般文字為基礎的文件。但其中包含兩個重大的特性：一個就是有關文件的格式命令 (稱之為標示Markup)﹔另一個則是包含連結至其他資源的指標 (稱之為超文本Hypertext或超連結Hyperlinks)。舉例來說，一份有關地震的文件，可能包含一個指標，可連至另一個研究大地板塊科學家所撰寫的有關文件。HTML的創始者，並沒有想到這項技術的功能會演變得如此強大有力。除了成為Internet蓬勃發展的主因外，更讓WWW得以迅速成長。

基本標籤(Tag Basics)

HTML文件是一個包含特殊程式碼的純文字檔，這些程式碼稱之為標籤(Tags)。它通常放置在一個區塊文字的外圍，而這些區塊文字與繞在外面的標籤常被一起稱之為元件 (Element)。透過一個網頁瀏覽器例如Microsoft Internet Explorer直譯器 (Interpreter)，或剖析器 (Parser)，來決定這些元件顯示在螢幕上的內容。在多數的情況下，每個元件都有一個起始 (opening) 標籤和結束 (closing) 標籤。起始標籤由標籤名稱和環繞在外面的三角括弧 ("<" 和 ">" 字元) 所組成。舉例來說，粗體的起始標籤被定義成 <B>。一個結束標籤也是被三角括弧所包住，但是在結束標籤中標籤名稱前面會加上一個斜線("/" forward slash): </B>。被影響到的文字會出現在起始標籤和結束標籤之間：當由瀏覽器在處理時，在 <B> 標籤和它的結束標籤 </B> 標籤之間的文字會以粗體顯示.1

為了要看看標籤使用，我們來分析一個簡單的網頁。程式列表2-1是一些簡單的原始碼，您可它來建立這樣的網頁，和圖2-1顯示Internet Explorer如何解讀這些程式碼。(本書所有程式列表，和範本檔案都可以在書附光碟中找到)。

<HTML>
<HEAD>
<TITLE>Listing 2-1</TITLE>
</HEAD>
<BODY>
Yet another "Hello World!"
</BODY>
</HTML>
程式2-1

HTML容器標籤 (Container Tags)

在程式列表2-1的第一個標籤 <HTML>，指示給瀏覽器之下的內容應該使用建立HTML的語法與結構規則來作處理。相對的結束標籤，</HTML>，會出現在檔案結尾。您不應該將任何元件放到這兩個標籤之外，因為可能出現無法預測的結果。

圖2-1 　一個基本網頁2
-

標頭標籤 (Header Tags)

<HEAD> 和 </HEAD> 標籤標示檔案之header區域的邊界，它包含一些不會直接在網頁上被呈現或顯示的項目。標頭基本上是可有可無的，雖然HTML的規格書中，強調一些元件只有在它的內部才可以被使用。例如：TITLE就是這種元件之一。<TITLE> 和 </TITLE> 標籤定義了瀏覽器標題列顯示的名稱 (在功能表上面的藍色區域)。因為Internet Explorer (就像大部分的瀏覽器) 會自動將瀏覽器名稱加到標題上，所以在程式列表2-1顯示的文件將會以 "Listing 2-1 - Microsoft Internet Explorer" 為標題。

主體標籤 (Body Tags)

在程式列表2-1中，接著是被 <BODY> 和 </BODY> 標籤所包圍的區域。正如所預期的，這個區域就是文件的主體部分。它包括了文件的內容－就是顯示在網頁上的內容。因此，例子中顯示的文字就是 "Yet Another "Hello World!"

字元格式標籤

如果前面例子就是HTML的功能極限，那麼設計網頁就會變得十分無趣。你可以從字元格式標籤獲得更多的設計靈感並可改變文字的外觀，參考程式列表2-2和圖2-2所示。3

程式列表2-2包含了幾個不同的基本字元格式標籤。在第一行中，粗體標籤 <B> 和 </B> 包在 "bold text" 周圍，然後這些字在圖2-2會顯示成粗體。在下一行中，<I> 和 </I> 標籤會讓 "italic text" 變斜體。許多其他字元格式標籤如下所示，包括 <U> 設定底線，<STRIKE> 設定刪除線，<KBD>設定固定寬度型態 ，<SUB> 和 <SUP> 分別可設定下標字和上標字。

<HTML>
<HEAD>
<TITLE>Listing 2-2</TITLE>
</HEAD>
<BODY>
This is some <B>bold text</B>.
This is some <I>italic text</I>.
This is some <U>underlined text</U>.
This is some <STRIKE>strikethrough text</STRIKE>.
This is some <KBD>fixed-width text</KBD>.
This is some <SUB>subscripted text</SUB>.
This is some <SUP>superscripted text</SUP>.
</BODY>
</HTML>
程式2-2

您可以使用 <FONT> 標籤來設定更多更複雜的文字格式。這個標籤支援不同的屬性 (Attribute)，包括COLOR、SIZE、和FACE、這些標籤的功用，就跟它們的名稱一樣。許多其他的標籤都支援屬性，有時候稱為參數 (Parameter)。

在程式列表2-3中，第一個 <FONT> 標籤展示了COLOR屬性的使用，它可以允許您改變文字顏色，COLOR屬性支援顏色範圍很大，從AliceBlue到YellowGreen。 您可以在SBN Workshop網站或書附光碟中的顏色表找到這些顏色名稱值的列表 (在CD中開啟workshop (references) 網頁中的DHTML﹔HTML & CSS﹔DHTML Object Model﹔references，然後在內容窗格中選擇顏色表。想要獲得線上版本，請連上MSDN線上資源網頁 ( msdn.microsoft.com/resources/schurmandhtml.htm )，或直接在光碟中開啟檔名MSDN_OL.htm，然後選擇顏色表)。COLOR屬性也支援16進位三原色RGB值，它的意思是說您可以使用16進位數字(如 #0000FF)。不用擔心如果您不熟悉這種方法，因為顏色對照列表會列出它相對的16進位碼。4

接著的 <FONT> 標籤包含SIZE屬性，它改變文字的相對大小。您可以設定1到7比例的文字大小，7是最大的。這些數字並無相對的任何特定點數或像素大小，且相同的大小設定在不同系統中會有變化 (將會在第三部份篇中，看到透過串接式樣式表CSS更精確的控制方法)。

圖2-2 一個格式字元範例的網頁
Note

在本書中，為了便於閱讀，HTML標籤都以大寫字母來顯示: 例如 <TITLE>。當撰寫自己的網頁時，不需跟隨這種規定，因為HTML是不區分大小寫的。換句話說，<BODY> ，<Body>和 <body> 都是相同的標籤。然而，某些其他Internet Explorer所支援的技術，如Microsoft JScript，是會區別大小寫的。JScript將在本書第二部分探討。

<HTML>
<HEAD>
<TITLE>Listing 2-3</TITLE>
</HEAD>
<BODY>
<FONT COLOR="blue">Color!</FONT>
<FONT SIZE="5">Size!</FONT>
<FONT FACE="Courier">Typeface!</FONT>
<FONT SIZE="6" COLOR="blue" FACE="Arial">Many Changes!</FONT>
</BODY>
</HTML>
程式2-3

在程式列表2-3的第三個 <FONT> 標籤使用FACE屬性來改變文字的字體。一般來說，使用預設文字是個不錯的方式 (這意味著在這個標籤中不設定任何字體)，因為很難預測使用者安裝且使用哪些字體。這種情況在Web環境下尤其常見，使用者平台範圍從PC上的Microsoft Windows NT，到Macintosh上的MacOS，或在Sun上的Solaris。一些常見可使用的字體包括Arial，Courier，和Times (Internet Explorer 4和5支援一種技術稱之為嵌入字型 (font embedding)，它讓您可以在網頁中嵌入字型，使用者可以從網頁下載這些字型﹔詳見5 第12章 )。

圖2-3　利用 <FONT> 標籤來設定字元格式

在HTML中，一個標籤可以有很多的屬性。舉例來說，在程式2-3中的最後一個 <FONT> 標籤設定large的藍色Arial文字，因為它的SIZE屬性設定成6，它的顏色屬性設定成Blue，且它的FACE屬性設定成Arial。這些屬性可以任意排列，得到的結果依然相同。

分行格式標籤

您可能會感到驚訝，在程式列表2-3中分行的HTML程式碼由Internet Explorer來瀏覽，會變成一個連續的一行文字。只有當文字到達瀏覽器視窗的邊界時，才會產生換行的動作 ( 圖2-3)。HTML標準明定，瀏覽器會忽略在來源純文字檔案中的換行結束符號 (linefeed和carriage return) (講更清楚一些，每個換行結束符號都被視為一個單一的whitespace，它是指任何顯示在電腦螢幕或列表機中的空白字元，它包括tab字元，space字元，和其他特殊字元。連續的whitespaces都被視為一個單一的空白)。所以，另一方面，一些特別的標籤就被使用來決定分行格式，正如程式列表2-4所示，圖2-4展示用Internet Explorer來瀏覽這個文件的結果。6

在程式列表2-4中BODY中的前第一二行的 <P> 和 </P> 這組標籤定義一個區塊的文字為一個段落。就像您可以在圖2-4中看到的，此組標籤造成每個段落的前後都會加上一個空白行。

結束標籤 </P> 是可選用的，若Internet Explorer遇到一個新的 <P> 標籤，它會自動將前一個段落結束。因此，Internet Explorer顯示下列HTML原始碼：

<P> This is a paragraph.</P>
<P> This is a another.</P>
<P>

若用同樣的方式瀏覽下面沒有結束標籤 </P> 的原始碼：

<P> This is a paragraph.
<P> This is a another.
<P>

兩個原始碼片段產生相同的結果。

在程式列表2-4中接著下面的兩行是level 1和level 2的標題文字。就像一個段落一樣，標題前後也都有一空白行。每一個標題level都有一個相對的特定字型大小。HTML內建定義了的6個層級標題; level 1的標題會顯示非常大的字型及level 6的標題會是十分小的字型。不同層級的標題大小之間並沒有直接比例關係，因此，一個層級3的標題並不是層級1或層級2的倍數。7

在程式列表2-4中的最後幾行中出現了一個換行符號(Break tag)，<BR>。這個標籤會插入一個line break ，不過不像 <P> 標籤，它並沒有插入任何額外的空白行。您不需要加入一個結束標籤 </BR> ，因為一個換行符號不會定義一個區域文字。當遇到 <BR> 標籤時，瀏覽器就會換行，您也可以使用多個 <BR> 標籤來插入多個line breaks。雖然有時這樣做看起來很笨，但這是一個簡單建立行與行之間隔的方法。

<HTML>
<HEAD>
<TITLE>Listing 2-4</TITLE>
</HEAD>
<BODY>
<P>This is an example of a paragraph.</P>
<P>This is another paragraph.</P>
<H1>This is a level-1 heading.</H1>
<H2>This is a level-2 heading.</H2>
This is not followed by a break.
This <B>is</B> followed by a break.
<BR>
This is not followed by a break.
This is not followed by a break.
</BODY>
</HTML>
程式2-4
Note

本書第三部分會解釋串接式樣式表 (CSS) ，這是一個十分新的標準，它允許對於所有格式最一個精確的控制，從對齊方式 (alignment) 和邊界寬度(margin width)，到文字的顏色和大小。CSS已經在許多網站中取代了 <FONT> 標籤。

圖2-4　一個包含行格式化標籤的網頁

當您的原始程式碼中有換行，您想要當有空格時就顯示空格，並強迫瀏覽器去忽略預設的whitespace處理和文字換行規則。可以利用 <PRE> 標籤來完成，如程式列表2-5所示，這告訴瀏覽器您已經事先格式化了這段文字。8

程式列表2-5也展示了horizontal rule標籤 <HR>，它可以橫跨網頁建立一條水平線或分隔線。<HR> 中兩個經常使用的屬性為SIZE和WIDTH。SIZE設定以pixel為單位的分隔線厚度，它可以從1改變到100 pixel。SIZE屬性預設值為2。WIDTH控制分隔線的寬度，您可以設定一個特定的pixel數，或設定一個螢幕可使用空間的百分比值。因此，<HR WIDTH="50"> 建立一個50 pixel寬度的水平分隔線，另一個例子 <HR WIDTH="50%"> 劃一條是瀏覽器視窗寬度之百分之50的分隔線，而WIDTH預設值為百分之百。最後在程式列表2-5中，我們看到一個no-break標籤 <NOBR> 的例子。任何放在 <NOBR> 元件裡面的元件將每行的結尾都不會自動換行。若您想要將文字或圖形放在一行，<NOBR> 可能就會十分有用。舉例來說，也許你會想將產品名稱，全部顯示在同一行中。

<HTML>
<HEAD>
<TITLE>Listing 2-5</TITLE>
</HEAD>
<BODY>
<PRE>
This is an example of some
    preformatted text.
Notice how     the page
 is displayed with the same spacing and
   line breaks as the code.
</PRE>
<HR>
<HR WIDTH="50%" SIZE="6">
One of these lines uses no-break and one does not.
<NOBR>One of these lines uses no-break and one does not.</NOBR>
</BODY>
</HTML>
程式2-5

圖 2-5 格式化文字、水平分隔線及 no-break 標籤的範例
Note

對於使用 <PRE> 有一個注意事項：當一行文字比瀏覽器顯示視窗寬度還長時，瀏覽器一般都會自動將文字換行。然而當使用 <PRE>，這就不會發生。因此，不謹慎的使用格式化文字會導致網頁需要使用者需要水平轉動來觀看到所有的文字，如圖2-5所示。

Note

一個設定成100 % 寬度的 <HR> 標籤通常都不會佔滿整個螢幕的寬度。一般而言，分隔線的兩邊都會留一個很小的邊界。您可以修正這個問題 (其他您想要將內容切齊到螢幕邊緣的情況也適用)，那就是利用減少<BODY> 標籤的邊界屬性。水平邊界可以利用設定 <BODY> 標籤的LEFTMATGIN屬性為0來刪除。垂直的邊界可以利用TOPMARGIN屬性來刪除。因此，下面這個 <BODY> 標籤可以完全刪除環繞在網頁周圍的邊界。9

<BODY LEFTMARGIN="0" TOPMARGIN="0">

您也可以這些屬性的數值來增加繞在網頁周圍的邊界大小。

對齊屬性和標籤(Alignment Attributes and Tags)

HTML也提供您控制網頁元件的水平方向位置。程式列表2-6展示了兩個方法，圖2-6展示結果。

<HTML>
<HEAD>
<TITLE>Listing 2-6</TITLE>
</HEAD>
<BODY>
<P ALIGN="left">This text is left-aligned.</P>
<H2 ALIGN="center">This text is centered.</H2>
<H5 ALIGN="right">This text is right-aligned.</H5>
<CENTER>This text is also centered.</CENTER>
</BODY>
</HTML>
程式2-6

瀏覽器預設是將所有的文字都往視窗左邊對齊 (left-aligned)。您可以改變這個預設值，方法就是使用ALIGN屬性。許多標籤都支援ALIGN屬性，包括 <P> 和所有的標題標籤。在程式2-6 BODY部分的前三行中，分別設定使用ALIGN來設定文字靠左、放置在視窗中間、和設定靠右。因為將文字置中是十分常見的，所以這種設定有一個獨立的標籤 <CENTER>，就如同您在 <BODY> 元件的最後一行所看到的。瀏覽器會將放置在 <CENTER> 和 </CENTER> 標籤中的任何文字放置在網頁中間。10

圖2-6　顯示文字對齊方式的網頁範例

圖像與超連結標籤 (image and hyperlink tags)

圖像與超連結提供一些HTML中最強大的功能。Internet Explorer讓您可顯示多采多姿的圖像類型，最常見就是GIF和JPEG (Graphics Interchange Format和Joint Photographic Experts Group，兩個十分常用的圖形檔案格式)。超連結定義了連結到遠端網頁的位置，或是同一網頁中的特定位置。程式2-4包含圖像和超連結，瀏覽結果在圖2-7。

<HTML>
<HEAD>
<TITLE>Listing 2-7</TITLE>
</HEAD>
<BODY>
Here is an image <IMG SRC="sample.gif" WIDTH="20" HEIGHT="36">.
<BR>
<IMG SRC="sample.gif" WIDTH="20" HEIGHT="36" ALIGN="right">
This image has been given an alignment. This causes the image to
be removed from the flow of the text and displayed at a particular
location relative to the surrounding text.
<BR>
Here is a <A HREF="http://www.microsoft.com">link to Microsoft</A>.
<BR>
The next link has a picture and text and links to a local file.
<BR>
<A HREF="other.htm"><IMG SRC="sample.gif"> text</A>
<BR>
This final link points to a bookmark in the file "other.htm".
<BR>
<A HREF="other.htm#bookmark1">Link to bookmark</A>
</BODY>
</HTML>
程式2-7

11
圖2-7　包括圖像與連結的網頁範例

使用 <IMG> 標籤來放置一個圖像到網頁上。結束標籤 </IMG> 是選用標籤，而且幾乎是不會使用到。一個圖像預設是一個行內 (in-line) 元件，意思是說它跟著文字移動，就像是一個文字一樣。圖像會影響換行環繞的方式，且圖像本身，會被周圍所影響文字的設定所影響，例如邊界(margins)。

<IMG> 標籤有很多屬性，是有關定義如何顯示圖像。最重要的就是SRC屬性，它包含一個來源圖檔的路徑。在程式2-7，我們使用本機上圖檔的命名方式 (此圖檔和HTML檔案放置在同一個目錄中)。您也可以在SRC屬性中指向其他位置的圖檔，例如在同一台電腦的另一個目錄上，或在其他網站上的圖檔。要使用其他目錄，只要在圖檔名稱前面加入路徑名稱，舉例來說，graphics/sample.gif若在另外一個網站上，即可使用圖檔的完整網頁位置，即前面加上http:// : 例如http://www.microsoft.com/library /images/gifs/ logos/ieget_ animated.gif。http:// 告訴瀏覽器存取檔案時使用HTTP (HyperText Transfer Protocol) 協定。網站上大部分的檔案，就是用此通訊協定來傳輸。

<IMG> 標籤中另外兩個常用的屬性，為寬度WIDTH和高度HEIGHT。兩者都是以像素數來代表。若您沒有設定寬度和高度，瀏覽器會先顯示一個預設固定大小的圖片放置位置，直到指定圖像下載完畢後，圖像接著會顯示成正確的大小，這樣通常會導致視窗中的文字回流。設定WIDTH和HEIGHT屬性讓瀏覽器能在真正圖像下載完之前，在視窗中保留一些空間。這個方式對於連線速度很慢的使用者來說，是十分有用的優點，因為可以讓瀏覽器顯示正確的網頁版面，讓版面配置更為快速。當WIDTH和HEIGHT屬性值不是圖形真正的寬度和高度時，會導致瀏覽器將圖形改變大小比例，將圖片調整為指定的面積。

在程式列表2-7中第二個 <IMG> 展示了ALIGN屬性。這個屬性會使圖像不會和文字一起在同一行中顯示。而會顯示在一個特別的位置，這個位置是相對於後面跟隨的文字而定。ALIGN的有效值包括top，bottom，middle，left，和right，它可以精確的設定圖片位置。一些不常用的設定值為absbottom、absmiddle、baseline、和texttop，這些設定值可根據使用字型的資訊計算圖像位置，以提供更多位置控制方法。很多其他的元件都支援ALIGN屬性，包括TABLE ( 第3章 會談到) 和FIELDSET (12 第4章 會談到)。

程式列表2-7也使用了超連結。一個超連結會被包圍在一組錨(Anchor) 標籤 <A> 和 </A> 之內，且通常會被設定成藍色與底線的格式。當使用者將滑鼠指標移到超連結的上方時，滑鼠指標會變成手狀指標。在連結中按一下鈕會使Internet Explorer開啟連結所指的網頁。

錨標籤支援HREF (Hypertext reference) 屬性，它可定義瀏覽器要前往的位址。這個位址可以是一個有效的Web位置﹔在程式2-7第一個超連結，我們選擇http://www.microsoft.com。若我們沒有在前面加上http://，瀏覽器會認為是一個目前伺服器一個名為www.microsoft.com的資料夾，而這是不存在的資料夾。您也可以利用HREF屬性來設定一個本地的檔案，正如我們這個例子中第二的錨標籤。設定other.htm的位置會使瀏覽器試著去開啟一個名為other.htm的檔案，而這個檔案與我們的例子放置在同一個目錄中。若我們設定為 "more/other.htm"，瀏覽器會到例子放置目錄的more子目錄中去找other.htm檔案。

Note

注意超連結圖像會顯示一個藍色框線在外圍，這個框線常是不必要的，且設計者經常都不想要顯示這種框線。您可設定IMG元件的BORDER屬性值為0將它取消框線設定。相反的，若您想要顯示更厚的圖像外框線，您可以將BORDER屬性設定更大的值，例如15或更大的值。

你還可以利用參考網頁書籤名稱 (Bookmark name) 的方式來連結，這個技巧經常使用在大型的文件中。在程式2-7中最後一個錨標籤就包含這種參考方式。當它被按下時，Internet Explorer會開啟other.htm接著會捲動捲軸到它到達所指示的標籤位置。

建立清單 (Constructing Lists)13

HTML包括了一組能建立階層列示清單 (hierarchical bulleted lists) 的標籤。共有兩種清單的類型﹔無序與有序。無序清單是利用小球項目圖示，而有序清單通常是利用數字標題顯示。您也可以將兩種形式合併來建立更複雜的清單。

無序清單 (Unsorted Lists)

首先我們來看看兩個無序清單，這些原始碼出現在程式列表2-8。圖2-8顯示清單，利用分隔線分開。

<HTML>
<HEAD>
<TITLE>Listing 2-8</TITLE>
</HEAD>
<BODY>

<UL>This is at the first level.
  <UL>This is at the second level.</UL>
  <UL>This is at the second level.
    <UL> This is at the third level.</UL>
  </UL>
  <UL>This is at the second level.</UL>
</UL>
<HR>
<UL>This is the first level header.
  <LI>This is the first level-1 item in the list.
  <LI>This is the second level-1 item in the list.
  <UL>
    <LI>This is the first level-2 item in the list.
    <LI>And this is the second level-2 item in the list.
  </UL>
  <LI>This is the third level-1 item in the list.
</UL>
</BODY>
</HTML>
程式2-8

圖2-8　一個無序清單的例子14
Note

HTML會忽略額外的空白。注意在程式2-8如何利用這項特性的優點，使用內縮 (indents) 效果，使視覺上看起來有分隔出清單階層的感覺。雖然寫作HTML並不需要將標題標籤內縮，但內縮的這幾行原始碼可視為一個功能強大的除錯方法，因為它可減少一些常見的錯誤 (如不小心遺漏一個標籤)。

程式列表2-8的第一行只由一組無序清單標籤所組成，<UL> 和 </UL> 標籤。要放置一組無序清單在另一組之內，可將清單嵌入另一個清單來建立一連串內縮的文字。注意每一個起始 <UL> 標籤，要對應一個結束 </UL> 標籤。

在程式列表2-8的第2個清單，是一個無序清單標籤 <UL>。結束標籤 </UL> 必須出現在清單的結束部分，代表這個清單已經結束了。任何放在這兩個標籤之間的元件，都被視為是清單的一部份。這個清單包含項目圖示項目，在文字前面使用清單項目標籤 <LI>。我們並不需要手動在每個項目中，加入結束標籤 </LI>。因為在另外一個項目開始之前，或清單結束之前所遇到任何的元件都視為目前清單項目的一部份。接下來另外有一個清單，被嵌入到這個清單中。這個嵌入清單被內縮，且它的項目圖示有不同的形狀。只有前三層嵌入的清單，擁有不同型態的項目圖示。由第三層開始，所有清單使用相同的項目圖示。注意第二層的 <UL> 標籤後面並沒有在任何文字，因為 <UL> 標題文字是可以選擇，要不要加入標題說明。

有序清單 (Ordered Lists)

一個有序清單的每一行項目符號都被顯示成數字，而非使用項目圖示。使用 <OL> 標籤便可設定出有序清單，如程式列表2-9。圖2-9顯示Internet Explorer瀏覽結果。

<HTML>
<HEAD>
<TITLE>Listing 2-9</TITLE>
</HEAD>
<BODY>
<OL>
  <LI>This is the first level-1 item in the list.
  <LI>This is the second level-1 item in the list.
  <OL>
    <LI>This is the first level-2 item in the list.
    <LI>And this is the second level-2 item in the list.
  </OL>
  <LI>This is the third level-1 item in the list.
</OL>
</BODY>
</HTML>
程式2-915

圖2-9　一個有序清單的例子

在程式列表2-9中由有序清單標籤 <OL> 開始，就像無序清單一樣，必須要加入結束標籤 </OL>。但現在每個清單項目前面放的是數字而非項目圖示。注意第二個清單被第一個清單所嵌入，且數字在第二個清單從新由1開始。

複雜的清單 (Complex lists)

<OL> 標籤支援一個屬性稱之為TYPE，它可以控制清單項目是否使用數字、字母或羅馬數字。程式列表2-10展示TYPE屬性配合與 <OL> 和 <UL> 標籤混合使用。您可以在圖2-10看到這個程式的執行結果。經由結合無序與有序清單及使用TYPE屬性，藉此展示複雜階層的資訊。

<HTML>
<HEAD>
<TITLE>Listing 2-10</TITLE>
</HEAD>
<BODY>
<OL TYPE="1">
  <LI>This uses numbers.
  <OL TYPE="A">
    <LI>This uses uppercase letters.
    <OL TYPE="a">
      <LI>This uses lowercase letters.
      <OL TYPE="I">
        <LI>This uses uppercase roman numerals.
        <OL TYPE="i">
          <LI>This uses lowercase roman numerals.
          <LI>This also uses lowercase roman numerals.
        </OL>
      </OL>
    </OL>
  </OL>
  <UL>
    <LI>Here is a bullet.
  </UL>
</OL>
</BODY>
</HTML>
程式2-1016

圖2-10　一個複雜清單的例子

現在，您應該熟悉了一些常用的HTML元件。在下一章中，我們將會探討兩個HTML所提供更強大的版面配置工具 ，表格和框架。


實戰Dynamic HTML網站技術=>表格及框架

表格及框架
小
工
具 加入書架
加入書籤
上一章
下一章

一個設計良好的網頁，除了看起來要順眼外，更應該能讓使用者快速找到所需的資料。在網頁設計中，框架及表格是最常拿來作為設計版面的工具。舉例來說，我們可利用表格將網頁畫面分成幾個不同的區域，每個區域顯示不同的內容。除此之外，表格還常被拿來當成版面的輔助定位工具使用。

若想在一個頁面中，同時顯示多份的HTML檔案，可使用框架來達成這個目標。框架可讓你在切換網頁時，讓畫面每個部分加以獨立處理。舉例來說，當網頁的標題或是索引需要保持在畫面中的某一區域時，就可以利用框架來完成這種功能。

表格

表格不僅僅只是簡單的顯示資料工具而已，它還是HTML中最有力的版面設計工具。同時表格所用的標籤，也有許多的變化。除了可以設定表格的邊框色彩及背景顏色外，還可以設定表格中內容的水平及垂直對齊方式。1

表格基本功能

表格的定義內容會被放在 <TABLE> 與 </TABLE> 之間，所以你可在這兩個標籤之間，加入相對的表格定位資料。程式碼列表3-1是一個簡單的表格範例，<TR> 與 </TR> 之間定義了資料列數，而 <TD> 與 </TD> 之間定義了每列中的資料欄數。圖3-1顯示了範例程式碼的結果。

將BORDER屬性設為1，可以在表格外加上1個點距寬的外框。若只增加這個數值的大小，表格的外框線會變寬，但表格內儲存格的外框仍會保持一點寬 (在下面的章節中，我們會進一步討論表格的格式設定問題)。

Note

因為HTML本身會忽略語法中不需要的空格，所以我們在範例程式碼3-1的地方，利用縮排的方式來表示不同表格的階層。在此 <TD> 標籤表示表格的一列 <TR> 中，有幾個儲存格。而 <TR> 標籤又縮排於 <TABLE> 標籤之下，用來代表 <TR> 是表格中每列的設定。當製作大型的複雜表格時，使用此種技巧可幫你快速找出表格中的錯誤，方便對表格進行除錯及維護工作。

<HTML>
<HEAD>
<TITLE>Listing 3-1</TITLE>
</HEAD>
<BODY>
<TABLE BORDER="1">
  <TR>
    <TD>R1, D1</TD>
    <TD>Row 1, Data 2</TD>
  </TR>
  <TR>
    <TD>Row 2, Data 1</TD>
    <TD>This is Row 2, Data Column 2</TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式3-1

2
圖3-1 簡單的表格

有關表格屬性的進一步說明

表格除了外框BORDER屬性外，還有許多的屬性可供設定。程式碼列表3-2中，將最常用的表格屬性套用在兩個不同的表格上，結果顯示在圖3-2中，

我們將第一個表格的BORDER外框寬度屬性設為5，而第二個表格的外框寬度設為10。在圖3-2中，我們可以明顯看出表格外框寬度所造成的不同效果。CELLPADDING屬性，可以控制儲存格內容與儲存格之間的距離﹔而CELLSPACING屬性，則控制了儲存格彼此之間的距離。在圖3-2的第1個表格，儲存格之間的距離就被設成相當的寬 (CELLSPACING被設成15)，但是儲存格 "內容" 與儲存格之間的距離 (CELLPADDING被設為2)，就被設成相當的短。而在第2個表格中，儲存格之間的距離就相對的比較短，而內容與儲存格間的距離就相對的比較長。

同時，你還可以在儲存格或是表格後面，利用修改BGCOLOR屬性，加上背景圖片。BGCOLOR屬性，控制了背景的顏色。在預設狀況下，背景顏色被設定為透明色。若您根據需要修改了儲存格或表格的BGCOLOR屬性，則顏色會依實際設定的順序而改變。

在程式碼列表及圖3-2中，我們將表格的背景顏色設為黃色，並且將第2列第一格的儲存格屬性設為白色。而最後顯示的結果，就只有特別設定為白色的儲存格是白色的，其餘的儲存格則是維持顯示黃色。

<HTML>
<HEAD>
<TITLE>Listing 3-2</TITLE>
</HEAD>
<BODY>
<TABLE BORDER="5" CELLPADDING="2" CELLSPACING="15" 	BGCOLOR="yellow">
  <TR>
    <TD>R1,D1</TD>
    <TD>Row 1, Data 2</TD>
  </TR>
  <TR>
    <TD BGCOLOR="white">Row 2, Data 1</TD>
    <TD BACKGROUND="back.gif">This is Row 2, Data Column 2</TD>	  </TR>
</TABLE>
<HR>
<TABLE BORDER="10" CELLPADDING="15" CELLSPACING="2" 	BACKGROUND="back.gif">
  <TR>
    <TD>R1,D1</TD>
    <TD>Row 1, Data 2</TD>
  </TR>
  <TR>
    <TD BGCOLOR="white">Row 2, Data 1</TD>
    <TD>This is Row 2, Data Column 2</TD>
  </TR>
</TABLE>
</BODY>
</HTML>3
程式3-2

圖3-2　在這兩個表格中，展示了兩種不同基本屬性的效果

BACKGROUND屬性可以讓你經由設定圖片路徑的方式，在儲存格或是整個表格背後放置一張圖片。第一個表格中，只有最後一個儲存格有圖片做為背景﹔第二個表格中，除了第二列的第一個儲存格外，其餘都套上了背景圖片。

這些只是最常見的屬性設定，還有其他更多的屬性可供使用者使用。BORDERCOLOR，BORDERCOLORLIGHT及BORDERCOLORDARK等屬性，可讓你對邊框做進一步的設定。而FRAME及RULES屬性，可控制顯示內框及外框的顯示方式。要建立表格的表頭及表尾，可以利用 <THEAD> 以及 <TFOOT> 標籤來執行。要組織表格內的資訊，可以利用 <TBODY> 標籤。<CAPTION> 可以用來替表格加上標籤，以方便管理 (在SBN Workshop的網頁上，及本書所附贈的CD中，包含了所有其他可使用標籤的進一步說明。可以參考CD的Workshop﹔DHTML，HTML&CSS﹔HTML Reference，及其下的Elements。要取得最新的線上版本，可以進入MSDN最新的線上說明網頁，以獲得最新的資訊 (msdn.Microsoft.com/resources/schurmandhtml.htm，或是打開書附光碟的MSDN_OL.htm檔，選擇HTML Tags及Attributes)。許多列出的屬性，在Netscape 3及Netscape 4中並不適用，例如前述的BGCOLOR及BACKGROUND。這些問題在舊版的Netscape 3中，最為明顯。

可變寬度的儲存格

並不是所有儲存格的大小，都被限定成一個樣子。舉例來說，表格的某些列可能只需要放兩個儲存格，而其餘的列中，則需要4個儲存格。為了提供表格設計的彈性，HTML提供了COLSAPN跟ROWSPAN兩個屬性，在程式碼列表3-3及圖3-3是COPSPAN屬性的範例說明。4

<HTML>
<HEAD>
<TITLE>Listing 3-3</TITLE>
</HEAD>
<BODY>
<TABLE BORDER="1">
  <TR>
    <TD COLSPAN="2" ALIGN="center">Row 1, Data 1</TD>
  </TR>
  <TR>
    <TD>Row 2, Data 1</TD>
    <TD>Row 2, Data 2</TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式3-3

圖3-3　COLSPAN屬性的說明範例

COLSAPN屬性，可以設定儲存格的寬度。通常儲存格都會佔用表格的一欄位置，但利用COLSAPN = 2的設定，可以設定儲存格佔用兩個欄位，將COLSAPN設定為4，可以將儲存格的寬度延長為4欄。在圖3-3中，將COLSPAN設為2可以將儲存格寬度設為和下方的兩個儲存格一樣寬。同時，也請注意我們已經將ALIGN屬性設成為置中，以對齊其中的內容 (儲存格預設的對齊方式是向左)。當你要做一個表格的標題時，這種合併儲存格後，再做置中效果是一種常見的方法。

接下來，我們看一下同時利用COLSPAN以及ROWSAPN屬性的進階範例，程式碼列表3-4中包含了範例程式碼，圖3-4則是Internet Explorer顯示的結果。

這個範例展示了兩種新的技巧，如何利用 ROWSPAN及空白的儲存格，來達成我們所需的效果。利用ROWSPAN屬性，你可以創造出合併幾列列高的儲存格。若需要做出某些類型的總計資料，這種儲存格就非常有用了。在此例中，我們將會拿來做apples及oranges的水果分類總計表。同時利用ROWSPAN及COLSPAN屬性，可以做出又寬又高的儲存格。但是本例中，並沒有做此示範。利用 <TD> 及 </TD> 敘述，我們在第2列中，可以快速的做出所需的空白儲存格。若我們沒有利用空白儲存格的技巧，Store1及Store2就會出現在表格的左邊，而不會被移到右邊。5

<HTML>
<HEAD>
<TITLE>Listing 3-4</TITLE>
</HEAD>
<BODY>
<TABLE BORDER="1">
  <TR>
    <TD COLSPAN="4" ALIGN="center"><B>Fruit Sales</B></TD>
  </TR>
  <TR>
    <TD></TD>
    <TD></TD>
    <TD>Store 1</TD>
    <TD>Store 2</TD>
  </TR>
  <TR>
    <TD ROWSPAN="2">Apples</TD>
    <TD>Day1</TD><TD>40</TD><TD>25</TD>
  </TR>
  <TR>
    <TD>Day2</TD><TD>30</TD><TD>30</TD>
  </TR>
  <TR>
    <TD ROWSPAN="2">Oranges</TD>
    <TD>Day1</TD><TD>40</TD><TD>25</TD>
  </TR>
  <TR>
    <TD>Day2</TD><TD>30</TD><TD>30</TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式3-4

圖3-4　使用COLSPAN屬性跟ROWSPAN屬性的表格

內嵌式的表格

內嵌式表格就是指那些在表格之內的表格，也就是說表格之內還有其他表格，或是表格之外還有其他表格。這個技巧在網頁的設計使用上，提供了許多的設計彈性。舉例來說，你可為表格每個部分，設計不一樣背景及邊框，而且使用上，也比ROWSPAN以及COLSPAN來得普遍。程式碼列表3-5展示了如何在一個大的表格內，放入其他兩個較小的表格。而圖3-5則顯示了最後的結果。

6
圖3-5　內嵌表格的範例
Note

在正常情況下，瀏覽器並不會需要您依照格式輸入表格。所以您可以在同一行敘述中，將多個資料欄位敘述輸入在同一行 (用 <TD> 及 </TD> 標籤將敘述包起來)，我們在程式碼列表3-4中，可以看到這種敘述方式。這種方式可以減少程式碼敘述所需的螢幕空間，但是卻犧牲了程式本身的可讀性。你看看Day1，40及25表格那一行，就知道筆者在說什麼了。

在圖3-5中，你可以看到外面較大的表格，裡面有兩個較小的表格。第一個和第四個儲存格中，只有簡單的數值資料 (數字1跟2)，而在第2個跟第4個儲存格中，則各內嵌有一個包含4個儲存格的資料表。

在第一個儲存格中，又出現了一個新的屬性VALIGN，它控制了儲存格內容的上下對齊方式。在本例中，我們設定了VALIGN屬性，所以儲存格的內容會向上方對齊。在第四個儲存格中，我們使用VALIGN屬性以及ALIGN屬性，來將儲存格的內容控制在右下方的角落。除此之外，我們還使用了BORDER屬性，來控制每個表格的外框線寬度。

<HTML>
<HEAD>
<TITLE>Listing 3-5</TITLE>
</HEAD>
<BODY>
<TABLE BORDER="1" CELLPADDING="5">
  <TR>
    <TD VALIGN="top">1</TD>
    <TD>
      <TABLE BORDER="2">
        <TR><TD>A</TD><TD>B</TD></TR>
        <TR><TD>C</TD><TD>D</TD></TR>
      </TABLE>
    </TD>
  </TR>
  <TR>
    <TD>
      <TABLE BORDER="5">
        <TR><TD>E</TD><TD>F</TD></TR>
        <TR><TD>G</TD><TD>H</TD></TR>
      </TABLE>
    </TD>
    <TD VALIGN="bottom" ALIGN="right">2</TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式3-5
Note

當你建立一個內嵌式的表格時，BORDER屬性可以幫助你進行表格除錯的工作。不論你是否需要這些邊框，但是這些邊框可以幫助你把表格的範圍看得更清楚。當你使用COLSPAN及ROWSPAN屬性製作複雜的表格時，這個觀念非常重要。而在使用內嵌的表格時，這種方式更為重要。7

使用表格當成版面配置工具

表格在傳統的HTML設計上，是非常重要的版面配置工具。當你搭配ALIGN及VALIGN敘述，以及表格的WIDTH以及HEIGHT屬性時，你幾乎可以將所需的物件擺放到網頁的任何地方。在程式碼列表3-6中，我們可以看到如何利用表格提供的版面配置功能，將不同的資料放到表格不同的部份中。同時，表格還會依照瀏覽器的視窗，自動調整至適當的大小。圖3-6顯示了Internet Explorer所顯示的結果。

圖3-6　使用表格來控制版面的範例
<HTML>
<HEAD>
<TITLE>Listing 3-6</TITLE>
</HEAD>
<BODY TOPMARGIN="0" LEFTMARGIN="0">
<TABLE WIDTH="100%" HEIGHT="100%" CELLSPACING="0" CELLPADDING="5"
BORDER="0">
  <TR>
    <TD COLSPAN="3" ALIGN="CENTER" BGCOLOR="black" HEIGHT="25">
      <FONT COLOR="white"><B>Page Using Tables</B></FONT>
    </TD>
  </TR>
  <TR>
    <TD BGCOLOR="thistle" WIDTH="70" VALIGN="top">
      <IMG SRC="trans.gif" WIDTH="70" HEIGHT="0" BORDER="0"><BR>
      <B>Listings</B><BR>
      <A HREF="lst3-1.htm">Listing 3-1</A><BR>
      <A HREF="lst3-2.htm">Listing 3-2</A><BR>
      <A HREF="lst3-3.htm">Listing 3-3</A><BR>
      <A HREF="lst3-4.htm">Listing 3-4</A><BR>
    </TD>
    <TD ALIGN="center">
      <IMG SRC="trans.gif" WIDTH="150" HEIGHT="0" BORDER="0"><BR>
      This page demonstrates using a table for page layout.<BR>
      It is organized with local links on the left, external links
      on the right, content in the center, and a header at the top.
    </TD>
    <TD VALIGN="top" WIDTH="25%" BGCOLOR="lightgrey">
      <IMG SRC="trans.gif" WIDTH="120" HEIGHT="1" BORDER="0"><BR>
      <B>Organizations</B><BR>
      <A HREF="http://www.microsoft.com">Microsoft</A><BR>
      <A HREF="http://mspress.microsoft.com">Microsoft Press</A><BR>
      <A HREF="http://www.w3.org">W3C</A><BR>
      <BR>
      <B>Useful Sites</B><BR>
      <A HREF="http://microsoft.com/Workshop">SBN Workshop</A><BR>
      <A HREF="http://msdn.microsoft.com/">MSDN</A><BR>
      <A HREF="http://www.webreference.com">WebReference.com</A><BR>
      <A HREF="http://www.webreview.com">WebReview.com</A><BR>
    </TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式3-6

表格的WIDTH及HEIGHT屬性可以設定成點圖素的數值，也可以設定成設定成相對於螢幕百分比的大小。在程式碼列表3-6中，我們將這兩個屬性分別設為100%，表示表格將會佔據所有瀏覽器螢幕的空間。一般來說，在一個HTML網頁的四周，會有一個細小的邊框，但是我們經由設定 <BODY> 標籤以及TOPMARGIN及LEFTMARGIN屬性設為0，便可將這些邊框移除 (可惜的是，Netscape並不完全執行這些屬性的設定，所以在周圍仍會看到較小的空白)。為了確保儲存格間沒有間隙，我們將CELLSPACING設為0。將視窗用表格劃分好後，就可以利用這些儲存格控制擺放的文字或圖片位置。將CELLSPACING設為5，避免了將表格中的文字跑超過儲存格的邊界。8

Note

一般來說，我們會使用百分比來控制WIDTH選項，而不是用點像素的多寡來控制選項。因為若使用者的解析度設定，和網頁設計者的使用設定不同，那麼用點像素來指定寬度的結果就會變得非常難看。舉例來說，若你建立一個640點像素寬的低解析度的畫面，若使用者使用1280乘以1024的顯示畫面，則使用者看到的網頁將只有半個螢幕。在本節稍後，我們將討論如何利用適當的比例設定，以及透明背景圖的運用，以製作出會隨螢幕大小變化的表格。

這個簡單的表格有3欄及2個橫列，第一格橫列將COLSPAN設為3，所以它能橫跨過整個螢幕。通常這種儲存格會被當成表格的標題使用。

而下一個橫列中則包含3個儲存格，第一個儲存格的寬度被設成70，所以儲存格寬度就是70個點像素寬。不過在這裡有一個隱藏的危機，就是某些較舊的瀏覽器，可能會無法解讀 <TD> 標籤內的WIDTH屬性，而所得到的結果，就是一個過窄的儲存格。但是這種瀏覽器通常不會把儲存格變得比其中內含的物件還小，因為如此，我們可以利用一個透明去背的Gif檔，來控制表格的最短寬度。在範例檔案中，我們使用一張一個點像素高及寬的trans.gif來完成這項工作，而且檔案大小只有0.043 K。在左下方的儲存格中使用此透明gif檔，並且設定對應 <IMG> 標籤的WIDTH以及HEIGHT屬性，如此我們便設定好了表格的最小寬度，而且所有的瀏覽器都應該能正常顯示這個設定。同時，我們在這個儲存格中也使用了VALIGN的top屬性設定，將儲存格的內容向上對齊。

而第2個儲存格則將內容朝中間對齊。一般來說，儲存格的內容會朝左邊及垂直中間對齊。所以在此例中，並不需要再做VALIGN額外的設定。因為這個儲存格沒有設定寬度，所以儲存格的實際寬度，就是左右兩個儲存格剩下的實際寬度。

最後一個儲存格將寬度設為25%。和本列第一個儲存格不同的地方，在於這個儲存格會隨瀏覽器顯示在螢幕上的寬度而改變。在儲存格內放入一個指定寬度的圖片，可以避免使用者縮小視窗時，儲存格小於特定的寬度。

當你利用表格來控制版面的輸出效果時，請注意邊框的BORDER屬性可以幫你許多大忙。舉例來說，若你想做出和程式碼列表3-6相同的效果，但是程式碼3-7卻有一些錯誤。此時外框屬性可以幫助你除錯。在此例中，儲存格中間有太多的空格，再進一步檢查的結果，COLSPACING被設定為10而不是0，造成了表格間過寬的錯誤。

9
圖3-7　使用BORDER屬性來替表格除錯
Note

在第一個欄位中，我們使用一個透明的圖檔來控制儲存格寬度，不會小於指定的最小值。同時還可以避免儲存格內的文字，因為寬度過短而造成意外的折行。但除了設定最小寬度來避免意外的文字折行外，我們還可以利用其他功能來避免發生折行的效果。舉例來說，我們可以在儲存格的 <TD> 標籤中，使用NOWRAP設定來避免意外的文件折行。我們同時可以使用空白字元的代碼，來取代原先的listing (listing 3-1而不是listing 3-1)。利用這種方式，瀏覽器會把listing 3-1當成是同一個字，而不會被拆成兩個字。你可以在第4章中，學到更多的字元使用說明。

<HTML>
<HEAD>
<TITLE>Listing 3-7</TITLE>
</HEAD>
<BODY TOPMARGIN="0" LEFTMARGIN="0">
<TABLE WIDTH="100%" HEIGHT="100%" CELLSPACING="10" CELLPADDING="5" 	BORDER="1">
  <TR>
    <TD COLSPAN="3" ALIGN="CENTER" BGCOLOR="black" HEIGHT="25">
      <FONT COLOR="white"><B>Page Using Tables</B></FONT>d
    </TD>
  </TR>
  <TR>
    <TD BGCOLOR="thistle" WIDTH="70" VALIGN="top">
      <IMG SRC="trans.gif" WIDTH="70" HEIGHT="0" BORDER="0"><BR>
      <B>Listings</B><BR>
      <A HREF="lst3-1.htm">Listing 3-1</A><BR>
      <A HREF="lst3-2.htm">Listing 3-2</A><BR>
      <A HREF="lst3-3.htm">Listing 3-3</A><BR>
      <A HREF="lst3-4.htm">Listing 3-4</A><BR>
    </TD>
    <TD ALIGN="center">
      <IMG SRC="trans.gif" WIDTH="150" HEIGHT="0" BORDER="0"><BR>
      This page demonstrates using a table for page layout.<BR>
      It is organized with local links on the left, external links
      on the right, content in the center, and a header at the top.
    </TD>
    <TD VALIGN="top" WIDTH="25%" BGCOLOR="lightgrey">
      <IMG SRC="trans.gif" WIDTH="120" HEIGHT="1" BORDER="0"><BR>
      <B>Organizations</B><BR>
      <A HREF="http://www.microsoft.com">Microsoft</A><BR>
      <A HREF="http://mspress.microsoft.com">Microsoft Press</A><BR>
      <A HREF="http://www.w3.org">W3C</A><BR>
      <BR>
      <B>Useful Sites</B><BR>
      <A HREF="http://microsoft.com/Workshop">SBN Workshop</A><BR>
      <A HREF="http://msdn.microsoft.com/">MSDN</A><BR>
      <A HREF="http://www.webreference.com">WebReference.com</A><BR>
      <A HREF="http://www.webreview.com">WebReview.com</A><BR>
      </TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式3-7

框架

利用框架 (Frame)你可以將一個網頁分成獨立的兩個部分，每個部分都各自對應到不同的HTML網頁。利用這種功能，我們可以讓使用者切換網頁時，仍然在視窗中保持另一個部分不變。舉例來說，網頁的廣告部分或是索引部分可以獨立成一個框架 (很像書本的索引)，當使用者按下索引時，另一個視窗的框架網頁就隨之改變。框架可以是很有用的工具，但同時也可能會產生許多的麻煩。

框架概論10

你可以利用FRAMESET標籤在文件中加入框架，也就是直接在文件中，告訴瀏覽器要如何分割網頁，以及每一個部分的內容是什麼。程式碼列表3-8中，顯示了簡單的包含框架網頁，而圖3-8是顯示在Internet Explorer上的結果。

Note

注意在程式碼列表3-8中，並沒有包含網頁的本文區域。為了避免隱藏的錯誤發生機會，HTML標準中規定了HTML網頁中可以包含框架或是一般的本文，但是兩者不能並存。在舊版的Internet Explorer中支援文件本文中使用框架，但是在Internet Explorer 4及5中取消了這個功能，以使這個功能更接近W3C的標準。

<HTML>
<HEAD>
<TITLE>Listing 3-8</TITLE>
</HEAD>
<FRAMESET COLS="50%,70,*">
  <FRAME SRC="1.htm">
  <FRAME SRC="2.htm">
  <FRAME SRC="3.htm">
</FRAMESET>
</HTML>
程式3-8

在程式碼3-8中，指向了書附光碟的1.htm，2.htm，3.htm檔案。在 <FRAMESET> 標籤中，我們使用了COLS屬性，代表網頁將會被分成3欄。而這3個參數則分別設定了3個欄位的寬度。第一個數值設定了框架將是瀏覽視窗的50% 寬，第2個參數則是70點寬，第3個參數則是將剩下的空間給第3個欄位 (利用 * 號表示)。若全部使用比率的方式來指定框架的大小，則框架會隨視窗大小而做調整。在圖3-8中，注意將框架分割的垂直線，使用者可以拉曳這些垂直線以調整框架的寬度。回到程式碼列表3-8，注意在 < FRAMESET> 中間的 <FRAME> 敘述，這些標籤中設定了每個框架中出現的網頁。

圖3-8　一個具有框架的網頁11

根據W3C組織的規格設定，Internet Explorer支援一種特殊的in-line框架，或稱為IFRAME。這種FRAME跟一般的FRAME不同，不需要使用FRAMESET的文件。它可以和IMG或TABLE一樣，包含在任何標準的網頁中。在第3個框架中包含了一個IFRAME，其中顯示了1.htm這個檔案。你可在原先顯示的3.htm檔案中，看到IFRAME的敘述。HTML敘述如下：

<HTML>
<BODY BGCOLOR ="blue">
This is frame number 3.
<BR>
<IFRAME SRC="1.htm" WIDTH="100">
</BODY>
</HTML>

要更進一步學習有關IFRAME的功能，可以參考SBN Workshop的網站以及書附光碟的內容。打開光碟目錄下的Workshop (Reference) 的HTML檔，指向DHTML & CSS﹔HTML Reference﹔以及Elements的內容。要閱讀線上文件，請參考 http://msdn.microsoft.com/resource/schurmandhtml.htm 的說明，或是開啟書附光碟的MSDN_OL.htm檔案，選擇HTML Tags and Attributes項目。目前Netscape的瀏覽器並不支援IFRAME標籤，當它閱讀到此標籤時，會自動略過去。

框架和表格一樣，支援內嵌以及套疊式 (nesting) 或稱巢狀式的架構。一個框架可以被內嵌到或是包含在另一個框架中。利用這個功能，你可以做出多層次的版面設計。程式碼列表3-9中，你可以看到利用frameset支援的許多屬性，以及套疊框架的效果。

<HTML>
<HEAD>
<TITLE>Listing 3-9</TITLE>
</HEAD>
<FRAMESET ROWS="50,*" FRAMEBORDER="0" FRAMESPACING="0">
  <FRAME SRC="1.htm" NAME="frame1" SCROLLING="no">
  <FRAMESET COLS="20%,80%" FRAMEBORDER="1" FRAMESPACING="1">
    <FRAME SRC="2.htm" NAME="frame2" SCROLLING="yes">
    <FRAME SRC="3.htm" NAME="frame3" SCROLLING="auto">
  </FRAMESET>
</FRAMESET>
</HTML>12
程式3-9

圖3-9　進階的frameset用法
Note

另一個建立套疊式框架的方法，是利用 <FRAME> 的SRC屬性指向另一個擁有框架的文件。我們可以利用指向一個包含框架文件的 <FRAME> 標籤，取代 <FRAMESET> 標籤，做出和程式碼列表3-9一樣的結果。雖然每一個取代的檔案結構都比程式碼列表3-9簡單，但是由於修改版面結構時，需要修改多個檔案，所以並不是很好的一種方法。

在程式碼列表3-9中，建立了兩欄的框架。第一個有50個像素寬，第二欄則佔據了剩餘的螢幕。第1列指向了1.htm檔案，第2列則指向了另兩個分割的框架，各佔有獨立的畫面區域。

FRAMEBORDER以及FRAMESPACING屬性控制了框架間的間隔距離，避免使用者重新調整框架的大小。你也可以仿造3-9例，將外圍框架的兩個屬性分別設為0，將上下框架的間距減少至0。這樣使用者看不到邊框，自然也就無法調整框架間的大小了。當你需要一個固定空間放網頁的廣告時，這個技巧就十分好用。注意在3-9中裡面的框架，因為沒有將FRAMEBORDER及FRAMESPACING設為0，所以框架的大小是可以調整的。不過目前的Netscape並不支援Internet Explorer所擁有的全部功能。

SCROLLING屬性決定視窗的捲動軸要不要出現，以及何時出現。當其設定為no時，則不會出現捲動軸。您應該避免使用這項設定，除非您確定在任何情況下都不需要捲動軸。例如，您的框架中沒包含任何文字，只有一個已知面積的圖像。其設定為Yes，表示捲動軸永遠會出現。設定auto時表示捲動軸只有當需要時才出現。auto設定特別有用，因為傳統HTML沒有提供當需要時就可隱藏捲動軸的方式。13

Note

即使你將SCROLLING設定為auto，瀏覽器會自動捲動到畫面的左邊，若你沒有保留足夠的空間，那麼使用者在瀏覽網頁時，網頁自動左移的結果，可能導致意料之外的結果。

在程式碼列表3-9的NAME屬性可以替框架命名，利用這種方式可以指定按下的超連結要顯示在哪個框架中，接下來我們作進一步解釋。

框架間的超連結使用

讓使用者能在不同的框架中，依照使用者選取的超連結，顯示不同內容的方式，大大的增加了網頁的方便性。一般來說，我們常利用這種功能，做出網頁的導覽頁。要做出這個效果，在導覽頁的網頁中必須利用錨點控制畫面要顯示在哪一個框架中。程式碼列表3-10是一個簡單的導覽列，Internet Explorer會顯示如圖3-10的導覽列以及結果。

<HTML>
<HEAD>
<TITLE>Listing 3-10</TITLE>
</HEAD>
<FRAMESET COLS="25%,75%" FRAMEBORDER="1" FRAMESPACING="1">
  <FRAME SRC="nav.htm" NAME="NavFrame" SCROLLING="yes">
  <FRAME SRC="1.htm" NAME="ContentFrame" SCROLLING="auto">
</FRAMESET>
</HTML>
程式3-10

14
圖3-10　框架與導覽列的設計範例

在程式碼3-10中，左邊的框架又有一個導覽列網頁nav.htm，其中包含了許多指向其他網頁的連結。

<HTML>
<BODY>
<A HREF="1.htm" TARGET="ContentFrame">Go to Frame 1</A><BR>

<A HREF="2.htm" TARGET="ContentFrame">Go to Frame 2</A><BR>
<A HREF="3.htm" TARGET="ContentFrame">Go to Frame 3</A><BR>
</BODY>
</HTML>

注意每個錨點都有一個TARGET屬性，代表這個超連結被按下時，結果要顯示在哪個框架中。在此列中，ContentFrame這個框架內容，將會隨著不同的超連結被按下，分別顯示1.htm，2.htm，3.htm。

TARGET屬性擁有一些特殊的屬性值可以設定，下面是一個簡單的列表 (你必須在設定值前加一個下橫線，每個參數必須小寫)。

  • _blank 代表文件將會開啟一個新視窗。
  • _self 代表文件將直接在包含連結的視窗開啟。15
  • _parent 代表文件將會開啟在包含此連結的母視窗中。一個框架的母視窗就是包含frameset的文件。
  • _top 目前的所有框架將被忽略，文件將會擁有完整的Internet Explorer視窗。

舉例來說，若希望一個超連結能夠跳脫目前的框架環境，可以利用下列的 _top敘述。

<A HERF="1.htm" TARGET="_top">Exit Frameset</A><BR>

而1.htm這個檔案將會取代原先的框架，佔滿整個Internet Explorer視窗。

若你指向 (TARGET) 了一個目前瀏覽器中不存在的框架名稱 (例如someotherframe)，瀏覽器將會開啟以該名稱為名的新視窗，並將TARGET指向的內容放進該視窗中。

Note

對於了解Scripting技術的人來說，還有許多的方法可以追蹤框架間的連結指向工作。在frameset最上方的框架被給予top的代碼，而目前使用的框架則稱為parent。top和parent這類的關鍵字，能與框架的名字搭配，進而存取其中的內容。舉例來說，在導覽列的NavFrame可以利用top.ContentFrame.myObject指向一個在ContentFrame的myObject (若對Scripting技術不熟也沒關係，本書第二部分將會一一深入討論其中的內容)。16

額外的考量

當設計一個包含框架的網頁時，你必須注意下列幾點：

  • 在每個網頁內每個框架，Internet Explorer都會下載相對的文件，間接增加了下載網頁所需的時間。
  • 大部分的瀏覽器都不允許使用者將網頁中的特定框架內容，加到我的最愛中，並只能將一般的預設首頁加進框架中。所以當使用者將包含框架的網頁加入我的最愛時，會發現只能將框架的主畫面加到我的最愛中，而不能儲存特定畫面的超連結。
  • 因為許多的瀏覽器並不支援框架 (雖然從Internet Explorer及Netscape 3.0版之後，都支援框架的功能)，你可以考慮在HTML中加上 <NOFRAMES> 標籤。若瀏覽器不支援框架，會直接顯示 <NOFRAMES> 與 </NOFRAMES> 的標籤間的文字說明內容。而說明文字的內容可以是指向非框架版本的網站，或直接建議使用者更換更新版本的瀏覽器。
  • 所有指向你的網站以外的TARGET敘述中，都應該將屬性值設為 _top。否則使用者會發現，他們似乎被限制在這個網站中了。

在網頁中使用框架是蠻有挑戰性的一件事，但是若妥善使用這個技術，框架可以戲劇性的改變網站的效能及風格。17

在下一章中我們將介紹如何製作表單，如何利用表單跟伺服器端交換資訊。還有字元本身的相關使用技術介紹，以輸入鍵盤上看不到的文字。還有其他不同的HTML相關技巧以及技術介紹。

實戰Dynamic HTML網站技術 視窗縮放
表格及框架


實戰Dynamic HTML網站技術=>表單、實用的 HTML 標籤、及字元的原形

表單、實用的 HTML 標籤、及字元的原形
小
工
具 加入書架
加入書籤
上一章
下一章

本章討論的重點，將放在前一章沒有討論的 HTML 內容。首先我們將介紹表單功能，以便收集網路上使用者的資料。稍後則會進一步介紹先前沒有介紹的特殊標籤，以提供網頁更多的特殊功能。最後，還會介紹如何在網頁上，不經由鍵盤，便可讓開發人員在內容中加入特殊字元的方法。

表單

在網頁上加上表單，可以增加使用者與網頁伺服器間的互動性。舉個簡單的例子來說，伺服器將含有表單的網頁傳送到使用者的瀏覽器上，請使用者輸入姓名、地址、電話號碼、年紀等基本資料。使用者填完表單後，便將輸入的結果傳送回伺服器。表單可以包含許多不同種類的元件，從簡單的文字方塊，到複雜的清單方塊到複雜的核選方塊，都可以被放到表單中。

讓我們先看看程式碼列表 4-1 所製作出的簡單表單，結果放在圖 4-1 中。1

<HTML>
<HEAD>
<TITLE>Listing 4-1</TITLE>
</HEAD>
<BODY>
<H1>This page contains a form.</H1>
<FORM NAME="F1" ACTION="http://ms.com/asp/prc.asp" METHOD="get">
<B>A text field follows.</B>
<INPUT TYPE="Text" NAME="txtFld" VALUE="A text field" SIZE="25">
<BR><INPUT TYPE="submit">
</FORM>
</BODY>
</HTML>
程式 4-1

表單標籤

FORM 標籤定義了表單的範圍，所有表單中所放置的元件 (文字方塊、核選方塊...等等)，都應該放在 <FORM> 跟 </FORM> 標籤之間。除此之外，<FORM> 標籤還支援了許多不同屬性。

圖4-1　簡單的表單範例

<FORM> 標籤的 NAME 屬性，當網頁上有多個不同的表單時，我們可以利用 NAME 屬性很快速的辨別不同表單中的資料。而 ACTION 屬性則設定了當使用者按下傳送 (SUBMIT) 鈕時，表單的資料要傳送到哪一個 URL 位址上。在程式列表 4-1 中，表單將會被 ms.com 網站下 asp 目錄的 prc.asp 檔案所處理。這個網站並不存在，所以當網頁傳送後，將會出現一個錯誤訊息。在 ACTION 命令中所傳送的檔案形式，是依伺服器所設定的形式而定。一般伺服器最常使用通用閘道介面 (Common Gateway Interface，CGI) 來處理表單。而 Microsoft 的 IIS 伺服器，提供了 Active Server Pages 技術，讓您可以快速而且有效率的處理，使用者所傳回的表單。因為表單的處理工作與伺服器端有相當密切的關係，所以本書不會教您怎樣撰寫 ASP 或是 CGI 程式。但是在大部分的情況下，本書所介紹的 Script 技術，大部分都可以應用到 ASP 的寫作技巧上。2

Method 屬性指定了表單傳回伺服器的形式，有兩個標準的選項可使用︰get 跟 post。Get 的作用有點像是定位點，當表單被傳送出來時，會依下列指定順序將表單內容傳回。

  • 在 ACTION 屬性下指定的位址。
  • 一個問號標記。
  • 表單的內容將會以 "名稱 = 數值" 的方式傳送至伺服器。

我們實際看一看結果，就可以了解方法其實很簡單。舉例來說︰ACTION 指定的http://www.ms.com/asp/prc.asp位置，使用者在 UserFirstName 下輸入了 John，表單將會連結到下列位址︰

http://www.ms.com/asp/prc.asp?UserFirstName=John

而伺服器上的 prc.asp 檔案，將會處理 ? 號之後的字串 (也就是查詢字串 query string)，也就是表單傳至伺服器的內容。使用者在瀏覽器的位址列上，將可以看到完整的位址字串 (包括 ? 號以及其後的字串)。一些特殊字元在位址欄中，可能看起來會起奇怪。舉例來說，若你將 = 號當成字串的一部份傳送，則傳送的數值將會被轉換成像是 %３D 的形式。以避免單純的傳送 = 號時，被伺服器誤認為 Name = Value 的形式。3

Note

當執行程式碼 4-1，並按下傳送鈕後，會出現一個錯誤的訊息。要正確執行這個表單，伺服器端必須要先設定好準備接受表單。在本章中，我們並沒有先做伺服器端的設計工作。不過即使會發生錯誤，你在客戶端的瀏覽器上，還是可以看到位址列出現連結位址名稱。

將 METHOD 屬性設定為 Post 時，傳送到伺服器的資料量將不會受到限制。當使用此方法傳遞資料時，在位址列上將可以看到表單的相關資訊。當處理大型複雜的表單，或是要增強表單的安全性時，Post 是最常用而且有用的方法。

應該使用哪一種 METHOD

你應該根據下列幾個條件，來選擇 METHOD 的方法。首先，雖然在大部分伺服器上的表單處理程式，都可以處理 post 跟 get 方法，但是它們彼此之間還是有一些差異及限制。這兩種方法最大的差異點，在於 get 會將位址列的 URL 當成是表單資料的一部份。這種方式有優點也有缺點︰其中一個缺點，是使用者會看到很醜陋的表單資料被傳送出去﹔有時為了某些安全因素，可能也不希望使用者看到這些資料。優點則是︰使用者可以將表單的資料，很完整的 (新增到 bookmark，例如我的最愛) 方式記下來。因為標記的內容中，就包括了完整的 URL 位址，以及表單的內容。除此之外，這些資訊可以讓某些特殊使用者，利用這些關鍵的表單數值 (name=value 數值)，直接連結到網站中的特定位址。當要傳送大量的資料時，post 方法可能是比較好的一種選擇。因為 get 方法傳送的內容，經常有 1000 個字元的限制。

INPUT 標籤

在程式碼列表 4-1 中，有兩個 <INPUT> 標籤，一個顯示了文字欄位，另一個則顯示了傳送鈕 (Submit)。<INPUT> 標籤非常的具有彈性，你可利用 INPUT 標籤，在表單中建立核選方塊及文字輸入方塊等各式內容。 程式列表 4-2 中，使用了 <INPUT> 標籤下，不同的 TYPE 格式設定。而在圖 4-2 中，顯示了程式的結果。

<HTML>
<HEAD>
<TITLE>Listing 4-2</TITLE>
</HEAD>
<BODY>
<FORM NAME="F1" ACTION="http://ms.com/asp/prc.asp" METHOD="get">
<INPUT NAME="t1" TYPE="text" VALUE="This is a text input"><BR>
<INPUT NAME="p1" TYPE="password" VALUE="A password input"><BR>
<INPUT NAME="c1" TYPE="checkbox" VALUE="Checkbox 1">
This text is next to check box 1.<BR>
<INPUT NAME="c2" TYPE="checkbox" VALUE="Checkbox 2">
This text is next to check box 2.<BR>
<INPUT NAME="r1" TYPE="radio" VALUE="first radio ">
This text is next to the first radio button.<BR>
<INPUT NAME="r1" TYPE="radio" VALUE="second radio">
This text is next to the second radio button.<BR>
<INPUT NAME="b1" TYPE="button" VALUE="Just a button"><BR>
<INPUT NAME="f1" TYPE="file" VALUE="This is a file input"><BR>
<INPUT NAME="h1" TYPE="hidden" VALUE="A hidden input"><BR>
<INPUT NAME="rst" TYPE="reset" VALUE="A reset button"><BR>
<INPUT NAME="sbt" TYPE="submit" VALUE="A submit button"><BR>
<INPUT NAME="i1" TYPE="image" VALUE="An Image" SRC="a.gif"><BR>
</FORM>
</BODY>
</HTML>4
程式4-2

圖4-2　各式不同的 INPUT 元件

每個 <INPUT> 標籤，應該都有 TYPE 跟 NAME 屬性，同時也常伴有 VALUE 屬性。經由 TYPE 屬性，可以設定使用者看到的輸入格式。所以同樣使用 <INPUT> 標籤，使用者實際所看到的可能是文字方塊、核選方塊、以及單選鈕等等。最後 NAME 所設定的名稱，和使用者所輸入的 VALUE 值，將會被傳回伺服器處理。傳回的結果就是我們先前所提到的 NAME = VALUE 字串。其他的屬性將會隨著 TYPE 屬性而稍有改變，在接下來的內容中，我們會一一看到。

把 TYPE 屬性值設為 text 時，在螢幕上會出現一個單行的文字輸入欄位。當要蒐集使用者的姓名以及地址資料時，這種輸入欄位就非常的有用。TYPE 的 text 屬性下，還可以設定欄位的可見長度 SIZE 值。除此之外，還可利用 MAXLENGTH 屬性限制使用者能輸入的最大字元數，或是將 READONLY 屬性值設為 true，以避免讓使用者輸入資料 (目前的 Netscape 瀏覽器還不支援 READONLY 屬性)。下面的標籤設定，將會產生一個寬度為 30 個字元長的文字方塊，但是使用者可經由捲動的方式，輸入長達 100 個字元。

<INPUT NAME="t1" TYPE="text" SIZE="30" MAXLENGTH="100">

在 VALUE 屬性下的起始設定值，會顯示在文字方塊中。若使用者修改了預設值，那麼當使用者按下傳送鈕送出表單時，最後使用者輸入的結果，將會被傳送到伺服器端。5

當 TYPE 屬性設定為 password 時，當使用者在文字方塊中輸入文字時，不會出現對應的文字，而是會用 * 號取代原來的輸入字元。這種方式可以讓客戶端在輸入密碼或其他敏感資料時，可以免於洩漏的危險。TYPE 等於 password 的可用屬性，和等於 text 的可用屬性相同。唯一的差異點，僅在顯示的方式不同。

當 TYPE 屬性設為 check box 時，螢幕上會出現一個標準的核選方塊。當加上 CHECKED 屬性時 (只要在標籤內加上 CHECKED) 這個字，就會出現一個已經被選取的核選方塊。只有當核選方塊在選取狀態時，表單中才會傳送 TYPE 為 check box 的內容。

當 TYPE 的數值設為 radio 時，出現的是標準的單選鈕。當設定 CHECKED 屬性時，單選鈕就會以選取的方式顯示。當表單中有一群選項時，單選鈕會被用來選出某個特定選項。所以你可以同時建立多個 TYPE 為 radio 的標籤，並使用相同的 NAME 屬性，在程式碼列表 4-2 中可以看到單選鈕的使用範例。當名稱屬性設為相同時，就等於將單選鈕編為同一個群組，讓使用者只能選取一個有效的選項。也就是說，當使用者選擇任一單選鈕時，前一個選取的標示將會被刪除。而最後選取的單選鈕名稱，以及按鈕相對應的數值，將會被傳送到伺服端。若單選鈕的群組中，使用者一個選項也沒選，那麼所有該按鈕的值將不會傳送回伺服端。

將 TYPE 屬性設為 button 時，將會在使用者的網頁上，出現一個按鈕。不論是否設定了按鈕上的數值 (也就是其上的文字)，按鈕依然可以執行相對的 Script。相關的 Scripting 方法將會在第二個部分描述。

而 TYPE 屬性設為 file 時，則網頁上會出現一個空白的文字方塊，以及 "瀏覽" 按鈕。這個按鈕可以讓使用者搜尋本機內的檔案位置 (在 Microsoft Internet Explorer 3 中，本身不支援這個標籤，除非使用者另行安裝了檔案上傳的增益集功能 (add-on))。當按下瀏覽鈕時，使用者的螢幕上會出現一個 "選擇檔案" 對話方塊，然後使用者就可以找到檔案在本機上的位置。為了使用者在使用此表單的安全因素，你不能事先指定表單上該標籤的 value。

TYPE 屬性設為 hidden 時，螢幕上使用者並不會看到任何的按鈕或文字方塊。hidden 標籤是用來暗中追蹤一些使用者不需要知道資訊。當需要與 Script 組合起來使用時，這種標籤可以當成一個方便的輸入工具。

將 TYPE 屬性設為 reset 時，在螢幕上會出現一個 "重設" 鈕。它可以將表單的資料，進行還原的工作。也就是說，表單的資料將會被恢復到第一次下載的狀態。若你額外設定了該標籤的 value 值，原本的 "重設" 按鈕文字將會被取代。當按下傳送鈕時，name = value 數值的組合字串將不會傳送回伺服端。因為這個標籤是在客戶端作用，而不是在伺服端作用。接下來的 "Submit" 及 "Image" 標籤功能也相當類似。6

將 TYPE 值設為 "submit" 時，螢幕上會出現 "送出查詢" 鈕。當按下此鈕時，表單的內容就會被傳送出去。當替按鈕設定額外的 value 時，按鈕上的文字就會跟著改變，而不會顯示原有的 "送出查詢" 內容。

另一種使用送出查詢的方法，是在 TYPE 標籤中使用 image 屬性。這個功能可使用一張圖片，來取代原有的 "送出查詢" 文字。當使用者按下此鈕時，表單也一樣會被傳送出去。當 <INPUT> 標籤使用 TYPE 為 image 的屬性時，可使用額外的兩種屬性值，分別是 SRC 跟 ALIGN。SRC 定義了替代圖案所放置的位置，而 ALIGN 指定了相對於其內文字的對齊方式，其使用方法和 <IMG> 標籤類似。

Text Area 標籤

除了 <INPUT> 標籤以外，表單還支援許多其他互動式的元件。<TEXTAREA> 標籤可以建立多行的文字輸入工具。程式碼列表 4-3 中描述了 <TEXTAREA> 標籤的用法，而圖 4-3 則顯示了執行的結果。

<HTML>
<HEAD>
<TITLE>Listing 4-3</TITLE>
</HEAD>
<BODY>
<FORM NAME="F1" ACTION="http://ms.com/asp/prc.asp" METHOD="GET">
<TEXTAREA NAME="TA1" COLS="40" ROWS="4" WRAP="soft">
  This text is inside TEXTAREA 1. Note how lines of code are
  automatically wrapped and how line breaks in the code cause
  breaks.
</TEXTAREA>
<BR>
<TEXTAREA NAME="TA2" COLS="40" ROWS="4" WRAP="off">
  This text is inside TEXTAREA 2. Note how lines of code are
  not automatically wrapped and how line breaks in the code
  cause breaks.
</TEXTAREA>
<BR><INPUT TYPE="submit">
</FORM>
</BODY>
</HTML>
程式 4-3

7
圖 4-3　使用 TEXTAREA 元件

<TEXTAREA> 標籤的功能，和 <INPUT> 標籤 TYPE 設為 text 時的功能相近，都允許輸入一行或多行的文字。但是 <TEXTAREA> 標籤容許同時輸入多行的文字。當表單被傳送出去時，所有在 TEXTAREA 中的資料，將會被當成該元件的數值傳送。而原先在標籤內的文字，會被當成預設的文字，在圖 4-3 中，我們可以明顯的看到這樣的情況。當使用者按下傳送鈕後，所有的使用這修改或是輸入的文字資料，將會被傳送到伺服端。

你可以利用 COLS 跟 ROWS 屬性，來決定 <TEXTAREA> 的區域大小。COLS 指定了文字區域的字元寬度，而 ROWS 則指定了捲動軸出現前，螢幕所能容納的列數。而 WRAP 屬性則決定了文字折行的方式。在 Internet Explorer 5 的預設狀態下，文字會自動折行，但是在 Netscape Navigator 中文字並不會自動的折行。當參數為 off 時，會關閉自動折行的效果，而當參數為 hard 或 soft 則可開啟折行效果。soft 跟 hard 的效果差別在於資料傳送到伺服器端時，有不同的處理方式。soft 不會送出斷行記號，而 hard 會送出螢幕上相對的斷行記號。Internet Explorer 還支援 READONLY 屬性，它可以讓區域內的文字無法編輯﹔以及 DIASABLED 屬性，它可以進一步將無法編輯的文字變成灰色。

SELECT 以及 OPTION 標籤

<SELECT> 及 <OPTION> 標籤可以做出清單方塊，供使用者選取清單中的項目。程式碼列表 4-4 中，顯示了 3 種清單方塊，而結果顯示在圖 4-4。

<HTML>
<HEAD>
<TITLE>Listing 4-4</TITLE>
</HEAD>
<BODY>
<FORM NAME="F1" ACTION="http://ms.com/asp/prc.asp" METHOD="get">
Select one item:
<SELECT NAME="sbt1">
  <OPTION VALUE="option1">Text of option 1
  <OPTION VALUE="option2" SELECTED>Text of option 2
  <OPTION VALUE="option3">Text of option 3
  <OPTION VALUE="option4">Text of option 4
  <OPTION VALUE="option5">Text of option 5
</SELECT>
<HR>
Select one item:
<SELECT NAME="sbt2" SIZE="3">
  <OPTION VALUE="option1">Text of option 1
  <OPTION VALUE="option2" SELECTED>Text of option 2
  <OPTION VALUE="option3">Text of option 3
  <OPTION VALUE="option4">Text of option 4
  <OPTION VALUE="option5">Text of option 5
</SELECT>
<HR>
Select multiple items:
<SELECT NAME="sbt3" MULTIPLE ALIGN="top">
  <OPTION VALUE="option1">Text of option 1
  <OPTION VALUE="option2" SELECTED>Text of option 2
  <OPTION VALUE="option3">Text of option 3
  <OPTION VALUE="option4">Text of option 4
  <OPTION VALUE="option5">Text of option 5
</SELECT>
<BR><INPUT TYPE="submit">
</FORM>
</BODY>
</HTML>
程式4-48

圖 4-4　製作下拉清單

<SELECT> 允許兩種清單，一種就是標準 (就是一般下拉式清單)，另一種則是多重選取清單 (multi-select)。在圖 4-4 中，我們可以清楚看到這兩個例子。而表列清單的區域，則是被限制在 SELECT 敘述中。在 SELECT 中還有 OPTION 選項需要設定，每個 OPTION 選項代表一個清單中的選取項目，OPTION 並不需要對應的 </OPTION> 標籤。SELECT 標籤下，也同時支援許多不同的屬性。若你設定了 MULTIPLE 屬性，下拉式清單將可容許使用者同時選取多個清單中的項目。使用者可以在選取項目時，按下 Ctrl 鍵一一選取所需的項目﹔或是按下 Shift 鍵一次選取多個範圍內的項目。

SIZE 屬性指定了預設的清單顯示列數，在標準下拉清單中，這個值是 1。所以使用只會看到一個捲動項目。若你指定的 SIZE 大小大於 1，則從選取項目下會顯示指定 SIZE 數目的項目。而多選的下拉清單中，預設項目顯示數量是 4，改變 SIZE 設定就可以改變顯示的項目數量。

每個 OPTION 項目都有一個 VALUE 屬性，當使用者按下傳送鈕將表單傳送出去時，SELECT 設定的名稱及所選取的數值，將會一併以 name = value 的形式傳送到伺服端。若你在 OPTION 中加入了 SELECTED 敘述，那這個項目就會變成預設的選取項目。每個 OPTION 項目還可以加上描述文字，以便使用者選取所需的項目。

在上面列出的所有項目，不論放在表單內外，都可以使用在 Internet Explorer 中。而 Netscape Navigator 則要求這些物件被放置在 FORM 的區塊中，否則就不能正常作用，只會像一般的文字顯示。舉例來說，在 SELECT 敘述下的 <OPTION> 文字，會以一般的文字出現，而不會以下拉清單的方式出現。

FORM 是非常實用的工具，但是許多更強力的功能，需要 Script 的協助。Scripting 的技術，將在本書的第二部分討論。9

其他有用的 HTML 標籤

除了我們先前討論過的 HTML 標籤外，在接下來的一節中我們將討論一些很有用的標籤。附錄 E 提供了一些 Internet Explorer 5 所支援的 HTML 標籤，其中還包括了簡單的功能敘述。而完整的參考說明，可以看書附光碟以及 SBN Workshop 網站的內容。打開書附光碟目錄下的 Workshop (Reference) 下的 DHTML、HTML&CSS，再進一步打開 HTML Reference 下的 Elements 的內容。要得到線上說明版本，可參考 msdn.Microsoft.com/resources/schurmandhtml.htm ，或是打開書附光碟的 MSDN_OL.htm 的內容，選擇檢視 HTML Tags and Attributes 的內容。

註解標籤

我們經常需要在 HTML 檔案中，加入使用者螢幕上看不到的註解文字。而這些註解文字，經常被用來：(1) 解釋 HTML 檔案的每個部分的功用是什麼﹔(2) 為什麼作者要這樣寫作程式﹔(3) 加上版權以及作者姓名之類，不希望使用者看到的資料﹔(4) 暫時讓 HTML 檔案中的部分功能失去作用。在程式碼列表 4-5 及圖 4-5 中，展示了兩種主要的 HTML 註解標籤用法。

<HTML>
<!--
Author:   Eric Schurman
Purpose:  Demonstrate comments
Location: Chapter 4
-->
<HEAD>
<TITLE>Listing 4-5</TITLE>
</HEAD>
<BODY>

<!--This is an example of a single line comment -->
<B>This is a normal block of HTML. The rest of the HTML
on this page does not display because it is disabled, or
<I>"commented out,"</I> through the use of comments.</B>

<!--This multi-line comment disables ("comments out") some HTML.
This <B>line of HTML</B> is commented out in both browsers.
-->

<COMMENT>This type of comment is part of HTML 4.0.</COMMENT>

<COMMENT>This one comments out some more HTML.
This is <B>yet more commented out HTML</B>. This type of
comment tag does not work in Netscape 3 and 4.
</COMMENT>

</BODY>
</HTML>10
程式 4-5

圖 4-5　不同的註解標籤使用方式

第一種註解標籤是使用 <!- - 開始，而以 - -> 作為結束。而在這兩個標籤之中的文字，將被視為註解處理，不會被顯示在使用者的螢幕上。這種標籤是最常見的註解標籤用法。在程式碼列表 4-5 中，第一個註解的內容是說明這個檔案的內容。注意一件事，就是註解標籤的開始和結束並不在同一行。在這個例子中，所有在標籤中間的文字都被當成是註解的一部份，所以它們並不會被顯示在螢幕上。第二個註解標籤是個單行的註解，開始與結束都在同一行。最後一個註解中間有一些 HTML 標籤，但是因被當成註解，所以並不會顯示在螢幕上。利用註解標籤使程式碼失去作用，是一種常見的註解使用技巧。這同時也是一種有力的除錯工具，因為你可以集中精神在程式碼的特定部分。除了可以快速縮小除錯範圍，更可以快速找出問題的所在。

第二種註解標籤則是使用 <COMMENT> 及 </COMMENT> 標籤。Internet Explorer 或是 Mosaic 的任何版本都支援這種標籤用法，但是目前的 Netscape Navigator 並不支援此種用法。在 Internet Explorer 中，這種標籤的作用和前一種提到的標籤相同，但是卻對 Netscape Navigator 的使用者無效。所以在 <COMMENT> 標籤中的內容，Netscape Navigator的使用者將看得到。這種因瀏覽器不同而產生的特性，有時也是一種方便的技巧。舉例來說，若想留給 Netscape Navigator 的使用者特定的訊息，就可以在 <COMMENT> 標籤中加入文字。Internet Explorer 的使用者看不到這些文字，而 Netscape Navigator 的使用者則看得到這些文字。

META 標籤

在前一個程式碼範例中，我們利用註解標籤在檔案的開頭提供文件的相關資訊。而 <META> 標籤除了可以提供網頁的內容說明外，還可以同時提供其他與網頁無直接相關的服務。舉例來說，我們可利用下面的 <META> 範例程式碼完成一些工作：11

  • 強迫網頁在指定秒數後重新整理一次 (以 5 秒為例)。

    <META HTTP - EQUIV ="REFRESH" CONTENT="5">
  • 讀入非英語系的字元集，如下例的日文字元集。當客戶端的的電腦安裝並支援該語系的字元時，指定的字元集才能正常顯示：

    <META HTTP - EQUIV = "Content - Type" CONTENT = "text/html﹔
    CHARSET = Windows - 51932">
  • 強迫該網頁無法被快取 (內容暫存在使用者端)，一些瀏覽器不支援這項功能。

    <META NAME = "Pragma" CONTENT = "No-Cache">
  • 指示網頁的內容將在何時過期，不讓瀏覽器從快取中讀取舊的網頁資料：12

    <META HTTP-EQUIV="Expires" CONTENT="Thursday, 18-Jan 96 16:26:30 GMT">
  • 在指定秒數後轉向不同的網頁

    <META HTTP - EQUIV = "Refresh" CONTENT="5;URL =
http://www.microsoft.com">
  • 提供搜尋網站來分析你自己網站的內容，你可以在這些標籤中，加入有關網站的介紹說明，網頁多久更新一次，以便提供搜尋網站相關的登錄資訊：

    <META NAME = "keywords" VALUE = "DHTML，CSS，ActiveX，HTML，	JScript">
<META NAME = "description" VALUE = "Description of DHTML.">
<META NAME = "type" CONTENT = "User Manual">
<META NAME ="revisit- after" CONTENT = "10 days">

<META> 標籤應該放在檔案中的 <HEAD> 標籤前。同時也要注意，大部分搜尋網站的自動搜尋程式，會忽略 <META> 標籤中重複太多次的字。所以你可以多用一些同義字，以及把說明放在 <META> 標籤的 keywords 中，會使得你的網站說明文字能夠更有效率的被分析網站的搜尋程式所應用。

許多的人會利用 <META> 標籤中，自訂的 NAME 屬性來追蹤一個網頁。舉書籍的例子來說，網頁 <META> 的 NAME 可能是 ISBN、Author、以及 Title。但是有些特殊的分析網站搜尋引擎，還是可以自動解讀對應的相關資料。13

FIELDSET 以及 LEGEND 標籤

<FIELDSET> 標籤以及 <LEGEND> 標籤是很有用的資料群組分類工具，經常被使用在表單上。<FIELDSET> 標籤可在其內的文字標題內容的四周畫一個框。<LEGEND> 標籤 (這個標籤在使用時，一定要緊接著放在 FIELDSET 的標籤下)。程式碼列表 4-6 提供了多種不同的 FIELDSET 的使用範例，而結果則可參考圖 4-6。

<HTML>
<HEAD>
<TITLE>Listing 4-6</TITLE>
</HEAD>
<BODY>
<FIELDSET>
This fieldset has no LEGEND.
</FIELDSET>
This text comes after Fieldset number 1.
This text comes after Fieldset number 1.
This text comes after Fieldset number 1.
<FIELDSET TITLE="A Fieldset">
<LEGEND>Fieldset 2</LEGEND>
This content is inside Fieldset 2.
</FIELDSET>
This text comes after Fieldset number 2.
This text comes after Fieldset number 2.
This text comes after Fieldset number 2.
<FIELDSET ALIGN="right" STYLE="width:140">
<LEGEND>Fieldset 3</LEGEND>
This content is inside Fieldset 3.
</FIELDSET>
This text comes after Fieldset number 3.
This text comes after Fieldset number 3.
This text comes after Fieldset number 3.
<FIELDSET>
<LEGEND ALIGN="center">Fieldset 4</LEGEND>
This content is inside Fieldset 4.
</FIELDSET>
This text comes after Fieldset number 4.
This text comes after Fieldset number 4.
This text comes after Fieldset number 4.
</BODY>
</HTML>
程式 4-6

大部分的程式碼列表功能都應該很清楚，而且不太需要另外再做說明。唯一值得注意的是第 3 個例子，FILEDSET 中同時使用了 ALIGN 以及 STYLE 屬性。ALIGN 控制了 FIELDSET 中間文字，相對於其外文字的對齊方式。而使用的方法，就和第 2 章提到的 IMG 標籤類似。一般來說，FIELDSET 會佔用整個螢幕的寬度，所以不太可能有多餘的空位擺放其他的文字。所以本例中，使用 STYLE 屬性將 FIELDSET 的寬度設為 140 點寬，便做出了保留的空位。STYLE 的說明在本書的第三部分，將會作深入的探討。

FIELDSET 標籤的說明是 HTML 4.0 規格的一部份，目前 Netscape Navigator 並不支援這個規格。而不支援這個標籤的瀏覽器，使用者看到的 FIELDSET 以及 LEGEND 標籤內容將是一般的文字。

14
圖 4-6　FIELDSET 與 LEGEND 標籤搭配的範例

影像地圖

一張影像地圖 (image map) 中，包含了許多不同的超連結。當使用者按下影像地圖不同的部分時，就會連結到不同的地方。影像地圖主要是由兩個部分所組成的，一個是 IMG 部分一個是 MAP 部分。IMG 部分 (請看 第2章 ) 是一個標準的 <IMG> 標籤再加上一個 USEMAP 屬性，可用來指定使用的地圖名稱。若 MAP 和 USEMAP 敘述在同一個檔案中，在地圖名稱前應該加一個 # 號。程式碼列表 4-7 以及圖 4-7 中，可以看到我們設定的結果。

<HTML>
<HEAD>
<TITLE>Listing 4-7</TITLE>
</HEAD>
<BODY>
<IMG SRC="nav.gif" WIDTH="300" HEIGHT="200" USEMAP="#NavMap">
<MAP NAME="NavMap">
<AREA SHAPE="rect" COORDS="0,0,50,100"
      HREF="http://www.microsoft.com">
<AREA SHAPE="circ" COORDS="100,150,20" HREF="http://www.w3c.org">
<AREA SHAPE="poly" COORDS="200,50,250,50,250,100,200,150,150,100" HREF="http://mspress.microsoft.com">
</MAP>
<BR>
<A HREF="http://www.microsoft.com">Microsoft</A>
<A HREF="http://www.w3c.org">W3C</A>
<A HREF="http://mspress.microsoft.com">Microsoft Press</A>
</BODY>
</HTML>
程式 4-715

圖 4-7　使用者按下圖形即可連結位址

MAP 敘述中可以放入多個 AREA 敘述，可利用 SHAPE、COORDS、以及 HREF 敘述影像地圖內分割區域的形狀、位置、以及對應的超連結。

你可以利用 rect 以及 rectangle 來畫出矩形區域，利用 circ 或是 circle 畫出圓形，利用 poly 或是 polygon 畫出多邊形。每一種圖形 (SHAPE) 用的 COORDS 座標屬性稍有不同。以圓形來說，COORDS 屬性的前 2 個參數是圓形的中心點座標位置，而座標的起始位置是從左上角開始計算。而第 3 個參數則是圓的半徑長度說明。而矩形的前 2 個參數，則是矩形左上方的座標，後 2 個參數，則是右下角的座標。多邊型的表示方式，則是每一對參數都代表了與另一點的相對座標，利用多點定位的方式即可做出多邊形。

在使用影像地圖時請注意，一定要加上當使用者看不到影像地圖的顯示文字。在程式碼列表 4-7 中包含了標準文字的超連結，這種設計可讓無法開啟圖形，或是盲人使用者也能使用網頁提供的服務。

Note

圖形周圍的外框，可以利用 IMG 的 BORDER 屬性消除。

Span 以及 Div 標籤16

<SPAN> 以及 <DIV> 標籤也就是所熟知的容器標籤 (Container tags)，它可以將一整個文字區塊獨立出來，但是卻不會對原先的格式內容造成影響。這個標籤常和串接樣式表 (Cascading Style Sheets，CSS) 一起使用，我們會在本書第三部分討論這個問題。

SPAN 是一個行內 (in-line) 的元件，也就是說它可以和標準文字結合在同一行中，但是卻不會造成斷行的結果。其他的行內元件像是有粗體 (B，boldface)、斜體 (I，italic)、底線 (U，underline) 等等。而 DIV 標籤就稍有不同，它會將文字斷行後自成一段。一些常見的段落元件，例如：段落 P (paragraph)，水平線 (HR，horizonal)﹔以及清單元件，例如：無順序性項目符號 (UL，unordered list)，有順序性的項目符號 (OL，ordered list)，以及清單項目符號 (LI，list item) 等。程式碼列表 4-8 是 SPAN 以及 DIV 標籤的使用範例，注意一下相似的程式碼，但是在圖 4-8 所造成的不同結果。

<HTML>
<HEAD>
<TITLE>Listing 4-8</TITLE>
</HEAD>
<BODY>
Here is <SPAN STYLE="font:bold 14pt">some text</SPAN> in a SPAN.
<HR>
Here is <DIV STYLE="font:bold 14pt">some text</DIV> in a DIV.
</BODY>
</HTML>
程式 4-8

圖 4-8　DIV 以及 SPAN 元件的基本用法

XMP (Example) 標籤17

<XMP> 標籤是一個非常有用的標籤，它的行為和 <PRE> 標籤有一點像 (在第 2 章中我們可以看到說明)。它可以顯示 HTML 的原始碼，而且顯示的內容保持和 HTML 原始文字相同。程式碼 4-9 是範例，圖 4-9 是結果。

<HTML>
<HEAD>
<TITLE>Listing 4-9</TITLE>
</HEAD>
<BODY>

<P>
This paragraph contains <B>bold</B>,
<I>italic</I>, and <U>underline</U> tags.
</P>

<XMP>
<P>
This paragraph contains <B>bold</B>,
<I>italic</I>, and <U>underline</U> tags.
</P>
</XMP>

</BODY>
</HTML>
程式 4-9

圖 4-9 XMP 標籤可以顯示其下的程式碼

Internet Explorer 可以依照我們的設定，正常顯示第一段的內容：所有在字型格式標籤 (<B>，<I>，<U>) 的文字會依照設定的格式顯示，而在 XMP 中顯示的文字就大不相同了，它會以原始檔的方式顯示文字內容，而不會進行格式化文件的工作。當要解釋 HTML 原始檔的功能時，這個技巧就非常有用了。

全球資訊網協會 (World Wide Web Consortium，W3C) 並不贊成使用這個標籤，並且建議不要再使用此標籤。但是 Internet Explorer 5 (以及第 3 及第 4 版) 為了保持相容性，還是保留 <XMP> 標籤的功能。目前還沒有任何的標籤提供類似 XMP 標籤的功能，但是可用接下來討論的 <PRE> 標籤及字元代碼，來完成類似的工作。18

字元的原形

字元的原形其實就是用來代表字元的代碼，每個螢幕上顯示的字元其實都有一個相對的代碼代表這個字。當需要顯示一個特殊字元或是不容易輸入的字元時，使用字元代碼就是一種不錯的方式。舉例來說，若要顯示一個小於的符號 (<)，但是因為它又代表了標籤的起始符號，所以瀏覽器會弄不清楚你真正的需求。所以你可以使用代表該字元的代碼，來避免隱藏的錯誤發生。程式碼列表 4-10 以及圖 4-10 說明了這種情況。

<HTML>
<HEAD>
<TITLE>Listing 4-10</TITLE>
</HEAD>
<BODY>

Display in bold that X is less than Y: <B> X&lt;Y </B>.
This paragraph uses a character entity.

<HR>

Display in bold that X is less than Y: <B> X<Y </B>.
This paragraph does not use a character entity.
</BODY>
</HTML>
程式 4-10

圖 4-10　字元代碼可以顯示對應的字元

第 1 個例子中，使用了字元代碼來代表小於的符號 (&lt)，而顯示結果也和我們所預期的一樣。而第 2 個例子中，直接使用了小於符號，所以它被當成粗體的標籤 </B> 的開頭，而且剩餘的文字也變成不正常的粗體。這都是因為不正確的小於符號，混淆了所有標籤中的內容所造成的結果。19

字元代碼可大略分成 3 個部分，第 1 個部分就是 & 號，瀏覽器可以根據這個字元，來判斷這個字元是否是字元代碼。接下來的部分可能是 # 號後面接著數字的代碼，或是直接的字元代碼名稱。所有的字元代碼都有數字型式的代號，但少數的常用字元有名稱可以直接使用。前例中的 < 符號就可以用 #60 或是 lt 來代表。最後一個字元代碼部分就是分號 (﹔)，讓瀏覽器知道代碼已經完整結束了。常用的代碼在附錄 D 的表 4-1 中，下一頁中也列出了常用的字元代碼。

Note

字元代碼的數值源自於 Unicode 2.0 的標準 (更精確的說，是 ISO 10646 字元集標準)，而其中包括了全世界各種語文的字元集。

在下一章中，我們將介紹文件物件架構 (Document Object Model)。這個方法的出現，大幅改變了 HTML 的現貌，替網頁文件增加了無窮潛力。

表 4-1
212629313536
顯示文字 | 數字代碼 | 名稱代碼20 | 描述 | 註解
 | &#09; |  | 水平標籤 |
 | &#13; |  | 換行 (Carriage return) |
 | &#32;22 |  | 空白鍵 (Space) |
! | &#33; |  | 驚嘆號23 |
" | &#34; | &quot; | 雙引號 | 常使用在 script 中
/24 | &#47; |  | 斜線 |
< | &#60; | &lt;25 | 小於 | 防止瀏覽器把小於符號當成一般標籤的開頭
> | &#62; | &gt; | 大於 |
\ | &#92; |  | 反斜線 |
... | &#133;27 |  | 省略符號 |
TM | &#153; |  | 商標28 |
 | &#160; | &nbsp; | 代表空白 | 當需要作版面微調時 (插入一個小空格)，或需要將兩個字分開，這項功能非常有用。
 | &#169; | &copy; | 版權 |
 | &#174; | &reg;30 | 註冊商標 |
 | &#177; | &plusmn; | 加或減 |
2 | &#178; | &sup2; | 2 的上標字 |
&#179; | &sup3;32 |  | 3 的上標字 |
&#185; | &sup1; |  | 1 的上標字33 |
&#188; | &frac14; |  | 4 分之 1 |
&#189;34 | &frac12; |  | 2 分之 1 |
&#190; | &frac34; |  | 4 分之 3 |
&#230; | &aelig; |  | ae 的連字小寫符號 |


實戰Dynamic HTML網站技術=>動態網頁物件模型

動態網頁物件模型
小
工
具 加入書架
加入書籤
上一章
下一章

傳統中的HTML文件都是靜態的網頁。就像本書每一頁一樣，一旦印刷後就不能改變。一個網頁顯示後，通常也就不能再進行改變。若要向使用者顯示新的資訊時，必須建立一個新的網頁。一些開發者為了避免這個限制，利用ActiveX控制項或Java Applets來顯示資訊，因為它們可以讓網頁內容動態的改變。但是這些方式也有很多限制，且需要使用者下載專用的元件或控制項。

在1996年Microsoft和一個名為SoftQuad的公司提出一份提案給全球資訊網協會 (World Wide Web Consortium;W3C)。這項提案制定了一個文件物件模型(Document Object Model)。這份提案中，大致規劃了一個瀏覽器，顯示HTML網頁的方式。它提供了一個標準的方法，來存取網頁文件的每個部分。在1998年10月1日，W3C提出了文件物件模型 (Document Object Model; 以後簡稱DOM) level 1的規格書。Microsoft Internet Explorer Dynamic HTML Object Model是Microsoft目前對於此提案標準所做的實作結果。

本章會講述動態網頁物件模型的基本概念，並探討其組成元件。在接下來的各章節中，我們將研究這些動態物件模型，以及如何透過script來操作、設計動態與互動的網頁。Netscape Navigator支援的物件模型與Internet Explorer的物件模型相當類似。然而Navigator的物件模型相較於Internet Explorer來說，功能限制較多且對網頁內容的控制能力較弱。

動態網頁物件模型的基本原則1

動態網頁物件模型主要是要達成下列目標：

  • 將網頁文件每個部分，定義成具有階層式的結構。
  • 可透過新增或刪除網頁內容，修改網頁的結構。
  • 提供一個可以監督和控制網頁內容的方法。
  • 提供資訊讓網頁中的所有項目之間，或與使用者之間能夠產生互動。

Internet Explorer的動態網頁模型，可讓一個程式開發者利用可程式化的控制方式，來控制網頁上所有的元件。並且在任何時候，都能視覺化的改變網頁上的物件。它可以傳達鍵盤和滑鼠的事件給瀏覽器，且甚至能讓開發者動態改變此網頁的HTML原始碼。任何改變都是立即呈現在使用者眼前。將動態網頁物件模型加入Internet Explore是Internet Explorer 4顯著的改變。

因為動態網頁物件模型中，定義了一些對於網頁前所未有的控制能力。所以它也激勵了開發者，在使用者與網頁之間，加入比以前更強大的功能。這裡有一些使用動態網頁物件模型，並配合script製作出的簡單實例：2

  • 當按下一個某個項目時，該項目下的索引可被展開或摺疊
  • 當使用者將滑鼠指標移到一個預設狀態的圖示按鈕上，那圖示改變成按鈕被選取的狀態，讓按鈕看起來像蹦出來一樣。
  • 使用者可以繞著網頁拉曳文字或圖形。
  • 元件不用使用者操作，就可以移動到設計者想要讓它停下來的精確位置上。
  • 當使用者將滑鼠指標移到圖形上面會出現提示文字。
  • 文字、圖像和表格的格式設定可以即時改變。
  • 因為使用者的輸入資訊，會使網頁的內容一部份被動態建立或刪除。3

動態網頁模型的基本元件

現在您已經看到動態網頁物件模型可以做什麼，我們來看看它的元件 (在接下來的討論中，我們將直接稱為物件模型或動態物件模型來代表動態網頁物件模型)。

物件 (Objects)

就像您在前幾章所看到的，一個HTML網頁包含許多元件，這些元件的型式，常常是由一組起始與結束標籤以及中間的內容所組成。一些元件還可將其他元件包含在內﹔舉例來說，一個表格的列 (TR) 元件，就包含在一個表格元件內。

每個網頁中的物件，都被完整定義在物件模型中，而物件是物件模型中一個最基本的單位。不論是影像、在SPAN標籤中的文字、HTML的BODY區域、或是ActiveX控制項，都是以文字方式被紀錄在網頁中的物件。

物件模型是以階層方式定義出所有物件，最高階層的物件是window物件，它代表目前顯示網頁的瀏覽器或框架視窗。所有在特定網頁中其他剩下的物件都是該網頁window物件的子物件。換句話說，代表所有HTML元件在物件模型階層中都比window物件還低。

如果一個網頁上的元件包含另外一個元件 (例如表格中的儲存格)，它在物件模型當中，會被代表物件包含的一個子物件(subobject)。當包含物件的物件被視為一個父親(Parent)物件時，它的子物件也常被稱為兒子 (Child) 物件。因此，表格是所有包含在表格內TR元件的父物件，且window物件是所有其他網頁中物件的父物件。4

在Internet Explorer中要參考物件，最常見的方式就是使用ID屬性來設定名稱。舉例來說，<IMG ID="MyImage"> 這段程式碼設定一個圖像物件的名稱是MyImage。另外，也可以使用NAME屬性，舉例來說，<FORM NAME="F1">。我們經常使用表單的名稱，幫助伺服端判斷是哪一個表單送出的資料。

一旦物件被命名後，它就可以輕易的透過script使用，您在 第7章 將會看到使用的範例。在大部分的情形下，物件的名稱都必須是獨一無二的。多個物件使用同樣的名稱，會引發很多的問題。

一個物件包含了屬性 (Properties)，事件(Events)，方法(Methods) 和集合(Collections)﹔完整的參考說明可以在SBN Workshop網站和書附光碟中找到。

打開CD中的Workshop (References) 網頁，指向其下的：DHTML，HTML & CSS﹔HTML References。若想看到線上最新的版本，請拜訪MSDN線上資源網頁 msdn.microsoft.com/resources/schurmandhtml.htm5 ，或開啟書附光碟中檔名為MSDN_OL.htm的檔案，且選擇DHTML Properties，Events，Methods，Collections。

屬性 (Properties)

在傳統的HTML中，您可以透過設定屬性來修改一個元件。屬性中提供了元件的相關資訊。因為一個HTML元件，在動態物件模型中會被當成是一個物件，而原本HTML元件的屬性，就會相對轉換成物件的屬性方式表示。舉例來說，這裡有一個簡單的圖像標籤：

<IMG SRC="oldpic.gif" WIDTH="10" ID="MyImage">

這個 <IMG> 標籤有三個HTML屬性：SRC，WIDTH，和ID。在網頁中，這些程式碼利用這三個屬性，建立出一個圖片元件；ID屬性是圖片的名字，且SRC和WIDTH分別設定圖片的來源和圖片的寬度。而這樣的元件在物件模型中，則變成代表一個物件，且三個屬性分別代表物件的src、width、id屬性。在物件模型中，這些屬性是可被存取的，意思就是它們可以透過script來讀取或修改。我們將在 第7章 說明，如何完成這項工作。6

除了src，width，和id屬性，在前一個例子中，物件模型定義中還可讓圖片物件有很多其他屬性使用。舉例來說，即使範例HTML原始碼並沒有包含 HEIGHT屬性，但我們可透過物件模型存取圖片物件的height屬性。事實上，IMG物件包含了大約50個屬性，它描述了從圖片對齊位置到來源檔案的建立時間等...，所有圖片相關資訊。

事件(Events)

Internet Explorer可以偵測到幾乎在網頁上發生的所有事件。舉例來說，若使用者在圖片上按一下時：瀏覽器會知道滑鼠被按了一下，而此時滑鼠指標在某一張特定圖片上。在網頁上的動作或發生的事情，例如：按一下滑鼠按鈕，都會被視為是一個事件。當網頁上發生一個事件，接收到事件的元件會提醒動態物件模型的機制，說明某事件已經發生了，這被稱之為觸發事件(firing the event)。若script設定捕捉此事件，就會立即對於事件觸發產生反應。當一個script會捕捉 (trapped) 或處理 (Handled) 這種被觸發的事件，此種script稱之為事件處理器 (Event Handler)。

瀏覽器能偵測很多不同類型的事件，這裡有一些針對滑鼠、鍵盤、和移動焦點的例子：

  • onmousedown事件 當使用者按下滑鼠鈕時觸發
  • onmouseover事件 當使用者將滑鼠指標移到某物件上方時觸發
  • onmouseout事件 當使用者將滑鼠指標移離某物件的範圍時觸發7
  • onkeypress事件 當使用者按鍵盤某一鍵時觸發
  • onfocus事件 當某物件獲得焦點時觸發
Note

當一個元件在選取狀態時，它就擁有焦點。在任何特定時間只能有一個元件獲得焦點。舉例來說，當填一個大型的線上表單時，它上面可能包含許多文字輸入欄位。您同一時間內，只能填入一個欄位。可填入的欄位就是目前焦點所在位置。在不同欄位上按鈕，來切換焦點給該欄位；或按 [TAB] 鍵的方式，將焦點切換到網頁不同的物件上。

onclick事件是一個特別的事件，它可被按下滑鼠按鈕或按下鍵盤按鍵觸發。這個事件設計來讓沒有滑鼠的使用者，也能存取網頁所設計。這裡列出觸發此事件的情況：

  • 使用者使用滑鼠按下一個物件。
  • 在一個擁有焦點的物件上，使用者按下Enter鍵。
  • 多選鈕或單選鈕 (radio button) 擁有焦點，然後使用者按下空白鍵。8
  • 使用者按下物件的鍵盤快速鍵 (就是熱鍵：HotKey)。熱鍵可利用accessKey性質來設定。

瀏覽器也支援其他特殊的事件，包括有：

  • onhelp事件 當使用者按下F1鍵時觸發。
  • onload事件 當一個物件完成下載時觸發。
  • onresize事件 當視窗被調整大小時觸發。
  • onscroll事件 當視窗的捲軸捲動時觸發。

您可以在SBN Workshop和書附光碟中，找到很多額外的事件及其對事件的解釋及敘述。Netscape Navigator支援的事件大部分與Internet Explorer相同，但是它並沒支援這麼多不同的物件捕捉事件。9

事件沸升(Event Bubbling)tc "事件沸升(Event Bubbling)"

Internet Explorer物件模型支援一個稱之為事件沸升的功能。當一個物件被一個事件觸發時，它也一併通知它的父物件，這個事件已經發生。此父物件再通知它的父物件。這個事件持續向上巡行或 "沸升" 到此階層結構，直到它到達頂點，或沸升動作被直接取消。在現實生活中相似的可能是向您的老闆要求加多一點薪水，然後這個要求就會往公司的階層結構往上傳送，直到它到達了可以決定這項要求的主管手邊為止。您可在 第7章 ，找到更多詳細有關事件沸升的資訊。

方法(Method)

方法描述了一個物件會採取的動作。舉例來說，window物件有一個方法稱之為open，它會指示window開啟一個新的瀏覽器視窗。

有些方法很普通，有些則十分特殊。舉例來說，幾乎所有物件都支援focus方法，它只是單純讓元件獲得焦點 (會導致物件觸發onfocus事件)。有些其他的方法只特別用於單一物件。舉例來說，使用ActiveX控制項來顯示電影會支援一個稱之為run的方法，它用來播放電影。另一個例子是reload方法，只有location物件擁有這個方法，它可使瀏覽器中目前網頁重新載入。10

集合(Collections)

集合一般來說是動態物件模型中最少用到的。集合是一個特定物件的一組元件串列。就像博物館中可能蒐集一堆圖畫，或圖書館會蒐集一堆圖書，物件模型也支援集合。舉例來說，document物件支援一個集合稱之為images，此代表所有在文件中所出現的圖像物件集合，以方便寫程式管理。

在本章中，我們已經探討了動態網頁物件模型背後的基本觀念。在第2部分，我們將會講述scripting，讓我們得以實作一下本章所說明的動態物件模型的的處理方式。在物件模型的環境下，Scripting提供一個有力、方便、快速的物件處理方式，它可以處理一些原本需利用傳統程式設計 (如：C++程式) 才能完成的工作。

實戰Dynamic HTML網站技術 視窗縮放
動態網頁物件模型


實戰Dynamic HTML網站技術=>Script 腳本語言簡介

Script 腳本語言簡介
小
工
具 加入書架
加入書籤
上一章
下一章

傳統的網頁瀏覽器中，一個最重要且最令人興奮的演進就是加入了Script語言 (Scripting)。透過了Script語言，網頁設計者可以在網頁上加入互動式及複雜的功能，而這些功能以往只出現在比較進階的應用程式上。Script腳本語言是被嵌入在網頁中的一段程式碼，在執行時才進行編譯動作。換句話說，一般HTML原始碼的文字檔中，還可以加上一些額外控制瀏覽器的文字。

Internet Explorer 5會解譯它所讀取的任何Script語言，來決定執行哪些動作。原理就和利用Internet Explorer 5經由解譯HTML，決定螢幕上顯示的內容一樣。這些Script必須利用網頁瀏覽器認識的特定程式語言來撰寫。舉例來說，程式列表6-1所示的網頁包含簡單的Script語言，當使用者在圖片上按鈕時，就會改變在網頁上的圖片。

<HTML>
<HEAD>
<TITLE>Listing 6-1</TITLE>
</HEAD>
<BODY>
<IMG ID="MyImage" SRC="oldpic.gif" onclick="MyImage.src='newpic.gif'">
</BODY>
</HTML>
程式6-11

本章將簡單說明Script語言，以及探討與 第5章 動態HTML物件模型的關聯，此外也會仔細研究一些基本的Script語言範例，例如：程式6-1所展示的內容。第二部份中剩下的幾個章節中，將提供更完整Script技術的討論內容。

Note

Netscape Navigator (即使在最近的4.7版 ) 並不完整支援Internet Explorer的動態HTML的物件模型。例如，它並不支援圖片上的onclick事件。所以使用Netscape開啟程式6-1時，儘管執行時不會產生錯誤訊息，但是在圖片上按鈕時並不會換圖片。在書附光碟的crosplat資料夾中， IENSSWAP.htm檔案可解決圖片轉換且可跨瀏覽器的解決方式。這個程式碼有點複雜，所以不適合在一開始討論Script語言時就介紹。在本書中隨時都會介紹跨瀏覽器的技巧，在 第23章 可看到更多相關技巧的說明。

在Internet Explorer中可使用Script語言2

Internet Explorer本身支援兩種Script語言：Microsoft Visual Basic Scripting Edtion (以後簡稱VBScript) 和Microsoft version of JavaScript ，簡稱JScript。

Internet Explorer也是一個Script語言的解讀平台，所以它也可以支援其他的Script語言，例如：可加入其他解譯程式來使用Perl。因此程式開發人員可以在Internet Explorer內，可使用他們熟悉的Script語言，而不用學習新的語言。你也可以在Internet Explorer中，使用先前使用其它語言寫的Script，而不用重新撰寫Script。當開發者在伺服端，要開發工具給有安裝特殊Script語言引擎的Internet Explorer客戶端使用時，此項功能就十分的有用。本書並不深入討論Script語言解讀平台技術，但是SBN Workshop網站及書附光碟中，都提供了一些不錯的資料來源。

Note

Perl是一個成熟的Script語言，在UNIX系統上十分普遍。它支援各種平台的獨立及網頁伺服器Script系統，包括所有32-bit版本的Windows系統。目前沒有主要的瀏覽器內建支援客戶端的Perl。Perl資訊可以在 http://www.activestate.com/ 和 http://www.perl.com/ 找到。3

VBScript

VBScript是微軟受歡迎程式語言Visual Basic的親戚。雖然IIS伺服器的ASP支援VBScript，但Internet Explorer是目前唯一支援VBScript的瀏覽器。VBScript對已經熟悉Visual Basic的程式設計師來說，是非常具有吸引力，但因為Visual Basic與VBScript語言大部分的結構與語法都相同 (或至少相似)，這使得學習VBScript相當容易。

Internet Explorer 5的精簡安裝中並不包含VBScript，不過當需要VBScript時，可以直接從網路上下載。此外，就像剛剛說的，VBScript除了Internet Explorer以外其他瀏覽器都不支援。正因為如此，所以本書使用Jscript語言來作例子，讓其他瀏覽器也能使用範例。

JavaScript和JScript

雖然由名稱上看來可能會以為JavaScript是Java的子集，但事實完全不是這樣。JavaScript是一個完全和Java不同的語言，而且是由不同的公司發展出來的 (Java是由Sun昇陽公司發展出來的；JavaScript則源自Netscape communication)。雖然它們源自於不同的公司，但JavaScript的確有一些與Java同名稱的結構與語法。Java開發者可以分別出Java語言與JavaScript不同。雖然JavaScript語法比VBScript嚴謹，但初學者會發現它在學習與使用上還是十分直覺 (事實上有經驗的Script語言撰寫者，通常偏好JavaScript。就是因為它在語法上比VBScript的語法更加嚴謹)。

JScript是另一個版本的JavaScript，內建在Internet Explorer裡面。在大部分的情況中，JScript和JavaScript幾乎完全相同。JavaScript和JScript已經各自發展一段時間，所以會導致一些在不同瀏覽器版本之間不相容的問題。歐洲電腦製造協會 (European Computer Manufacturer's Association) 發展了一個標準 (ECMAScript或ECMA-262)，它包含了JavaScript和JScript的核心特性。雖然Internet Explorer 4及以後的版本，和Netscape Navigator 4.06或以後的版本，各自支援一些附加功能，不過都支援ECMA-262，我們將會使用JScript來撰寫本書的Script語言範例。和上面所列的其他Script語言一樣，很多網頁伺服器都支援JScript / JavaScript。

Note

SBN Workshop網站和書附光碟都有Jscript的參考資料，這些資料在往後的章節中將會經常被提到，或參閱微軟網站的JScript區4 http://msdn.Microsoft.com/scripting 。

Script語言的功能

Script語言提供了很棒的功能，不過也有與生俱來的限制。從好處來看Script(在簡單的形式中) 十分容易學習使用，並可以在客戶端執行。用Script語言開發程式十分快速，且功能強大。反過來說，Script語言卻有一些安全性上的限制，所以在計算的操作上，不會比傳統編譯語言 (如C++) 快，同時複雜性也受到一些限制。

容易使用 基本Script語言是非常容易學習使用，Script提供非程式設計師很多程式設計上的強大功能。例如可利用一段簡單的程式碼，對使用者的動作 (事件驅動程式碼) 作出反應。例如讓使用者在特定圖片上按鈕時，就去執行一段程式。利用Script語言，您可以避免掉一些傳統程式設計所花費的時間及困難工作，例如：記憶體管理和無用記憶體空間的收集 (Garbage Collection)。此外，您不需要特殊的工具或開發平台環境，就可以開始撰寫Script。所有擁有瀏覽器及簡單的文字編輯器的人，就可以享受Script所帶來的好處。

客戶端處理5 另一個優點是Script語言在客戶端執行。一旦網頁已經被下載後，此網頁所有的Script都會在使用者瀏覽器上執行，而非在世界另一端的伺服器上 (當組合應用其他的功能時，如：格式檢查、多媒體、動態網頁物件模型，這個優點就會變得更重要。您將會在稍後看到實際的範例)。以往要修改網頁的內容或是外觀時，都需要對網頁作修改。但使用Script時，就可以利用Script的特性將網頁作動態變化。任何人使用可解譯Script的瀏覽器瀏覽網頁時，就能自動執行您的Script，不需另加額外的軟體，使用者可能甚至不必知道Script有否被執行，一點都感覺不到瀏覽器的存在。

快速開發 Script是直譯語言，所以不像C++ 或其他傳統程式語言需要編譯後才能執行。一個網頁開發者可以在HTML文件中建立Script後，直接在瀏覽器上執行。如要更改Script，只要編輯HTML檔案後重新載入一次，馬上就可以看到改變的效果。

功能強大 儘管Script十分簡單，但它的功能可是非常強大的。初學者可以盡情享受學習簡單的優點。另一方面，進階程式設計師則喜歡使用Script的彈性、進階和強大的功能。如物件導向 (Object Orientation)、在執行期間建立物件的能力、支援多種資料型態、以及虛擬控制瀏覽器所有元件... 等等。Script可讓網頁設計者加入複雜的邏輯到他們的網頁上，使得網頁產生動態且互動的效果。

安全議題 在瀏覽器中的Script受到一些限制。除了一些非常特定的例子上 (舉例來說，cookies，Default Behaviors和FileSystem的ActiveX控制項)，Internet Explorer不允許Script程式在硬碟讀寫檔案。這項限制，是為了預防喜歡惡作劇的網頁程式設計師，將使用者的硬碟損壞或竊取他們的資料。當需要使用Script當成開發工具，需要執行大規模的硬碟存取工作時，可以利用Windows Scripting Host，它允許您在Windows中使用Script。您也可以使用FileSystem的ActiveX控制項 (使用者必須特地准許載入這個控制項)，如此便可讓您在網頁上使用Script來控制檔案系統與硬碟。6

效能 因為VBScript和JScript都是為了使用容易所設計，所以它的效能並沒有比傳統編譯程式語言好。舉例來說，JScript可以撰寫一個複雜計算的編碼程式，但它的執行速度一定慢的嚇人。一般來說，這並不算一個很大的限制。因為大部分在瀏覽器上執行的工作，不需要如此高的計算效能。

複雜度 一個常見的錯誤觀念就是覺得一般的Scripting都很簡單，就認為所有的Scripting都很簡單。事實上VBScript和JScript都是複雜的語言，要徹底精通它們需要對程式設計觀念有徹底的了解。由於這部分很複雜，初學者在第一次接觸進階的Script時，感到手足無措。但是很幸運地，大部分的使用者不需要進階的Scripting技術，因為絕大部分的功能只要撰寫簡單的事件驅動程式就辦得到。

總而言之，當Script完全發揮瀏覽器所有強大的功能時，您將會發現Script在建立複雜且互動的網頁上是一個無價之寶。現在我們就來看看Script如何運作的。

HTML中的Script

每一個在HTML的元件都有一個標籤，Script也不例外。在大部分的情況中，為了讓瀏覽器可以辨識且正確地執行Script，它必須放置在一組Script標籤中。Script標籤通常如下所示：7

<SCRIPT LANGUAGE="JavaScript">
<!--
[真正的Script程式碼]
//-->
</SCRIPT>

第一行是Script的開頭標籤，就像您在區塊元件(Block) 例如粗體字(<B>) 或標題 (<TITLE>) 都需要有一個開頭的標籤，所以你也需要一個Script的開頭標籤 (<SCRIPT>)。第一行也設定了使用何種語言，它用來區別特定Script區塊是使用何種語言。(雖然在Internet Explorer中，LANGUAGE屬性可以設定成JavaScript或JScript，但是我們還是將LANGUAGE屬性設成JavaScript而不是JScript，因為其他的瀏覽器並不一定認得JScript的Script標籤)。您可能會想兩種Script可不可以放在同一個網頁中呢? 答案就是：你當然可以在同一個頁面上，不同的Script區塊中使用不同的Script語言。例如在同一個網頁上，同時使用VBScript和JScript。而不同的區塊間，甚至可以互相引用，但是這方式將會多花掉一些網頁的載入時間，與損失效能上的表現。

<!-- 和 --> 符號是HTML註解標籤的開頭和結尾。如此可以讓瀏覽器不會顯示註解文字在電腦螢幕上。因為較舊的瀏覽器無法辨識Script，所以會忽略在註解標籤之間包括Script在內的所有文字。如果設計的網頁是針對比較新的瀏覽器，就不需要這道手續。兩條斜線 (//) 代表該行是JScript的註解，在這個例子中，它把 --> 標籤當成註解，這可以避免在Netscape Navigator讀取此網頁發生的錯誤。因為若 --> 放在Script元件內，Netscape Navigator就會把這些字元當作Script來執行。此程式碼最後一行是結束標籤 </SCRIPT>。它被用來當成Script的結束標籤，就像 </TITLE> 標籤是網頁標題的結束標籤一樣。

除了將Script敘述包在Script起始與結束標籤之間外，你還可以將Script標籤指向一個Script的外部檔案。類似利用 <IMG> 標籤參考一個圖檔來顯示一樣，同樣必須透過SRC屬性來完成。舉例來說，如果您有一個外部檔案jsLibrary.js，可以用下面的方法參考外部Script：

<SCRIPT LANGUAGE="JavaScript" SRC="jsLibrary.js"></SCRIPT>

使用外部Script檔案有許多優點，若有一些Script是網站上許多不同網頁都會存取到的。只要將Script放置在外部檔案中，讓每個網頁使用參考的方式讀取，便可讓所有網頁使用同一個來源資料，也可避免因為在不同檔案中使用不同版本的Script而產生的不可預期問題。除此之外，Script檔案一旦下載之後，Script檔案就被暫存起來 (儲存在本地使用者的機器中)，這樣Script不需每次當成是個別網頁的一部份來載入，這樣可以大大減少下載時間。這個技術可使用在Netscape Navigator 3及以後的版本，以及Internet Explorer 3.02及以後的版本。

最後，網頁中的特定元件發生之事件處理的Scripts可直接加入元件中。此種Scripts被稱為嵌入事件處理器 (Embedded event handlers)，將在後面的章節中說明。8

將Script加入網頁中

正如在 第5章 所學到的，幾乎所有的Internet Explorer元件及大部分Netscape元件－從圖片到網頁本身的背景顏色－都可以被視為物件。這表示所有物件都可以透過Script來叫用。我們將會使用這項功能來展示一些基本的Scripting技術，這項觀念將會在 第7章 詳述。

程式列表6-2顯示一個有image標籤的網頁，我們將會以此例為基礎在網頁中加入Script。9

<HTML>
<HEAD>
<TITLE>Listing 6-2</TITLE>
</HEAD>
<BODY>
<IMG ID="MyImage" SRC="oldpic.gif">
</BODY>
</HTML>
程式6-2

在程式列表6-2中的原始碼是標準的HTML檔案。<IMG> 標籤指向了一個圖片。我們利用這個標籤的ID屬性給予圖片一個名稱－以這個例子來說，就是MyImage。這樣可讓我們更容易在稍後透過動態物件模型 (Dynamic Object Model) 使用這個圖片。Image標籤的最後利用SRC屬性來設定那個圖片的來源：Internet Explorer現在會在螢幕上顯示檔名為oldpic.gif的圖片。

現在我們來建立一些可以設定圖片的效果的Script：

<SCRIPT LANGUAGE="JavaScript" >
<!--
MyImage.src="newpic.gif"
//-->
</SCRIPT>

這個Script的重點在下面此行：MyImage.src="newpic.gif"。在原本的HTML檔中(程式列表6-2)，我們設定了MyImage image標籤的SRC屬性。在動態物件模型中，我們要設定MyImage物件的src屬性。舉例來說，要設定一個物件的特定屬性，物件名稱後加一個英文句點，然後在輸入屬性名稱： MyImage.src (想了解更多命名習慣，請參閱 第7章10 中有關 "命名標示法" 的附帶說明)。當Script執行時，將會透過動態物件模型來存取MyImage物件，並將src屬性值從oldpic.gif修改成newpic.gif。所以Internet Explorer就會改變顯示圖片為newpic.gif。

基本事件處理器

前面的程式看起來非常不錯，我們有一個內含圖片的網頁，且有一個Script程式可以將原先的圖片變成另一個圖片。我們接下來要作合併的工作，並讓Internet Explorer知道何時該呼叫Script來改變圖片。

大部分的Scripts都是當某些事件發生時才被觸發。舉例來說，載入HTML網頁是一個事件。移動滑鼠是另一個事件。網頁中不管何時發生事件，Internet Explorer都會知道。處理事件的Scripts就把事件交給對應的事件處理器 (Event Handlers)，以便作進一步處理。程式列表6-3加入一個事件處理器，當MyImage物件被滑鼠按鈕時，會執行該Script。這種事件處理器只有Internet Explorer支援。稍後討論的嵌入式事件處理器，就比較普遍被支援。

<HTML>
<HEAD>
<TITLE>Listing 6-3</TITLE>
<SCRIPT LANGUAGE="JavaScript" FOR="MyImage" EVENT="onclick">
<!--
MyImage.src="newpic.gif"
//-->
</SCRIPT>
</HEAD>
<BODY>
<IMG ID="MyImage" SRC="oldpic.gif">
</BODY>
</HTML>
程式6-3

在程式列表6-3中的事件處理器，直接出現在<SCRIPT>標籤之內。它包括兩個部分：FOR屬性讓Script知道我們關心的物件名稱為MyImage﹔ EVENT屬性決定哪一個事件將被處理。在本例中，要處理的事件是onclick (按下滑鼠按鈕)。因此，當使用者在MyImage物件這個圖片上按鈕時，這個Script區塊將被觸發。想要看看這個Script的執行情形，請開啟書附光碟中chap06資料夾中的lst6-3.htm。當Internet Explorer顯示網頁時，在圖片的左上方按滑鼠按鈕，來看看圖片如何改變。在Internet Explorer的工具列上按下重新整理鈕或按下鍵盤功能鍵F5，便可重新整理網頁回復它原來的狀態重新測試。11

Note

注意一下我們在程式列表6-3中，將script插入在HEAD區域。Script可以插入網頁中的任何地方，端視設計者的喜好及網頁實際需要。將所有的Scripts都放在同一個HTML網頁的區域上，可讓尋找Script和除錯更容易，將script放置在HEAD區域，也可確定Script在網頁其他的部分之前載入，當要除錯時這會十分有用。

嵌入事件處理器

嵌入事件處理器通常比程式列表6-3的程式更容易建立。為了要嵌入一個事件處理器，我們可以將處理事件的程式碼，插入目的標籤本身，如程式列表6-4。

<HTML>
<HEAD>
<TITLE>Listing 6-4</TITLE>
</HEAD>
<BODY>
<IMG ID="MyImage" SRC="oldpic.gif" onclick="MyImage.src='newpic.gif'">
</BODY>
</HTML>
程式6-4

程式列表6-4的程式執行結果就剛好跟前一個網頁一樣；當使用者按下圖片，就會變換圖片。但是現在image標籤中，包含了當在圖片上按鈕時所產生onclick事件的事件處理器。在這個例子當中，onclick的設定值為MyImage.src ='newpic.gif'。請注意這個設定和程式列表6-3中的 <SCRIPT> 區塊的內容完全相同，除了使用引號的不同以外。在程式列表6-4中，雙引號符號將整個onclick敘述包含起來，這個敘述說明當圖片被按鈕時該發生些什麼事，在這個敘述之內，單引號括住了圖片檔名newpic.gif。雙引號告訴Internet Explorer哪裡是事件處理器的開頭及結束，舉例來說，如果我們在第一個單引號中就是使用雙引號而非單引號，則onclick敘述會提早被結束。我們也可以將兩種引號交換使用，使用單引號來括住事件處理器程式碼及用雙引號來括住檔名。重要的是：只要在每一個程式碼前後，使用相同的引號種類將其括住就好。

嵌入式事件處理器只有一些限制。同時只有JavaScript及JScript支援它﹔ VBScript並不支援。他們也會使HTML有些難以閱讀，特別是如果您使用一個多重命令的長字串。您可以在12 第7章 學到更多有關事件處理的主題。

函式

目前您在本章所接觸到的Script都限定在網頁上某特定物件的特定事件 (例如：MyImage物件的Click事件)。為了使Script能處理多重物件發生的多重事件，我們可以建立自己的一套Script，每個圖片有屬於自己的事件處理器。但是這項技巧需要牽涉較多Script和較多的維護工作。幸運的是，還有更好的方法。

函式 (Function) 是一個程式區塊，而這段程式區塊可用我們所設定的名稱重複呼叫。我們先將特定事件的Script處理程式碼，自原先的Script分離出來，再把分離出來的處理程式變成一個函式。如此便可讓多個不同的事件同時呼叫這個函式來處理，範例如下所示：

<SCRIPT LANGUGAE="JavaScript">
<!--
function changeImage(){
   MyImage.src="newpic.gif"
}
//-->
</SCRIPT>
Note

因為本書都是針對目前支援 <SCRIPT> 標籤瀏覽器所設計的例子，所以我們在本書剩下來章節的範例中都將省略 <!-- 和 //--> 符號。如果您的網頁也想要讓那些看不懂Script的瀏覽器瀏覽 (例如Netscape Navigator 1.0版或一些純文字瀏覽器)，請主動適當的加上註解標籤。13

請注意我們將 <SCRIPT> 中的事件處理器部分 (FOR和EVENT屬性) 刪除，然後將Script內容部分變成函式。在這個例子中，函式的名稱為changeImage。我們可以透過這個函式名稱，從網頁中任何地方呼叫函式內部的程式碼。

因為函式通常都是執行一個動作，所以很適合利用動詞命名。而函式名稱後面，必須跟加上括弧。在大多進階的函式中，您還會看到括弧內會有一些引數名稱。在範例函式中括弧是空的表示我們並沒有傳任何值到函式中 (現在您不必擔心不清楚傳值問題，我們將會在 第9章 詳細說明函式引數)。

還有一個要注意的地方是大括弧 { 和 } 放置在函式名稱之後和Script結束之前。Jscript使用這些大括弧，方便分辨每個區塊中的程式碼。

我們現在需要一個事件來驅動這個函式。下面這個HTML程式碼包含了一個嵌入式事件處理器：

<BODY>
<IMG ID="MyImage" SRC="oldpic.gif" onclick="changeImage()">
</BODY>14

我們加入到 <IMG> 標籤的onclick處理器已經被設定成changeImage() 函式。這就是告訴Internet Explorer當使用者在圖片上按鈕時，就執行changeImage函式。換句話說，onclick事件處理器會呼叫changeImage函式來執行。現在我們來看看會有哪些結果。程式列表6-5將HTML放回跟Script程式碼在一起。當您執行此程式碼時 (在隨書光碟中chap06\lst6-5.htm)，它的執行結果，和程式列表6-3與程式列表6-4差不多。不過現在這個Script變成一個函式，所以可以被任何呼叫函式的事件所使用。而此函式目前被放在網頁的HEAD的區段中。

<HTML>
<HEAD>
<TITLE>Listing 6-5</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function changeImage(){
  MyImage.src="newpic.gif"
}
</SCRIPT>
</HEAD>
<BODY>
<IMG ID="MyImage" SRC="oldpic.gif" onclick="changeImage()">
<H1 onclick="changeImage()">Click here or on the image.</H1>
</BODY>
</HTML>
程式6-5

這個程式碼顯示了多個元件，呼叫同一個函式的情形。ChangeImage函式被MyImage物件和H1元件所呼叫。針對這個Script，不論在圖片或是文字上按鈕，都會改變畫面上的圖形 (不要忘記您可以按F5鈕來重新整理網頁，或直接按工具列的重新整理鈕)。

講到這裡，您應該有一些基本概念，了解如何利用Script增加網頁的功能與彈性，我們稍後會針對這些概念做更詳細的研究。在接下來的幾章中，我們將會深入研究Scripting如何與動態物件模型來做互動聯繫。接著我們會探討JavaScript和JScript所支援的資料型態，以及如何處理這些資料。然後接著說明如何使用函式、條件敘述、及迴圈來做Script的流程控制。最後一個Script章節中，將會討論一些如錯誤處理 (Error Handling) ...等進階的Scripting功能。

實戰Dynamic HTML網站技術 視窗縮放
Script 腳本語言簡介


實戰Dynamic HTML網站技術=>物件導向式的Scripting 技術

物件導向式的Scripting 技術
小
工
具 加入書架
加入書籤
上一章
下一章

在 第5章 中，我們介紹了物件模型 (Object Model) 的觀念，它被瀏覽器使用來表示網頁內部結構。在 第6章1 中，我們做了一個Scripting的概要說明。物件模型的特性，就是它可透過Scripting來作物件的控制。本章將詳細說明如何利用Scripts處理與使用物件模型。

物件值得注意的地方

在Internet Explorer的物件模型中，在網頁上的每個HTML元件都是物件與其他物件的結合，但是在HTML文件中並不一定會完整的宣告物件的格式。舉例來說：網頁物件都隸屬於window物件與document物件衍生的子物件，但使用時並看不到這兩個物件宣告。下面的列表提供你會遇到的一些物件：

A           BUTTON      DIV             document
event       history     IMG             location
navigator   screen      selection       SPAN
style       TABLE       userProfile     window

在 附錄C 中，您將會發現有一張所有標準物件 (為Internet Explorer物件模型的一部份) 的完整列表。所有物件的完整描述亦可在SBN Workshop網站和書附光碟中找到。在書附光碟中，請依序參閱Workshop (References) 網頁下的DHTML，HTML & CSS;DHTML References;Objects。若想瀏覽線上的版本，請拜訪MSDN線上資源網頁2 http://msdn.microsoft.com/resources/schumandhtml.htm ，或開啟書附光碟中MSDN_OL.htm檔案，選擇DHTML Objects。Netscape Navigator物件模型和Internet Explorer有點不同。我們會在本章剩下的部分中，講述Netscape Navigator與Internet Explorer之間的不同點。

Note

從前面的物件列表中, 可以看出物件名稱使用大小寫的情況並不一致。物件利用大寫顯示的 (例如IMG和SPAN) 是標準的HTML元件。物件顯示成大小寫混用或都是小寫字母，並不是HTML元件，而是整個物件模型的外加功能， 例如：screen物件包含前端使用者顯示器的資訊，而navigator物件提供有關瀏覽器版本和使用何種瀏覽器等資訊。

讀取和改變屬性

屬性描述了物件的特性，舉例來說，一個IMG物件有width和height屬性， 它定義了圖像的放置範圍。另外src屬性，則指定了IMG物件的來源圖檔位置。在Internet Explorer中，幾乎所有屬性都能透過Script讀取及操作。程式列表7-1是一個範例。圖7-1展示此程式一開頭顯示的樣子；圖7-2展示使用者按下確定鈕後的結果。

Note

就如同剛剛所說的，在Netscape Navigator並不提供像Internet Explorer一般的完整物件及功能。所以Netscape Navigator (到目前的版本4為止) 在本章中可使用的範例也不會太多，包括程式列表7-1在內。雖然Navigator並不能使用此程式所介紹的技巧，來存取特定的圖片。不過您仍可透過document物件的image集合來讀取 (但不能改變) 一個圖像的屬性。因此使用Img1.width (如程式7-1) 的敘述，可改變為document.images[0].width。在 第24章3 中，會介紹更多跨瀏覽器 (Cross-browser) 的Scripting技巧。

<HTML>
<HEAD>
<TITLE>Listing 7-1</TITLE>
</HEAD>
<BODY>
<IMG ID="Img1" SRC="circle.gif">
<SCRIPT LANGUAGE="JavaScript">
alert("Img1 has width "+Img1.width+" and height "+Img1.height)
Img1.height=150
Img1.width=30
alert("Now it has width "+Img1.width+" and height "+Img1.height)
</SCRIPT>
</BODY>
</HTML>
程式7-1

圖7-1　此交談窗顯示圖片的寬度和高度

圖7-2　當圖片改變時，交談窗顯示新屬性的設定值4

在這個例子中，我們的HTML網頁包含一個名為Img1的圖片物件。這段Script一開始會產生一個警告對話方塊 (alert dialog box)，上面顯示著目前的圖片寬度與高度。在物件模型的命名規則中，Script用加上句點的方式 (dot notation) 來取得相關的長寬資料 (請參考一下稍後 "表示法和命名方式" 的說明框，以獲得更多資訊)。雖然很多不同的物件上都有width以及height屬性，但是在程式7-1中， Img1.width和Img1.height表示式只使用到Img1物件的width和height屬性。在程式7-1中伴隨在這些敘述式的加號，並不是命名慣例的一部份。它是被用來將引號括起來的文字片段與屬性值，連結起來產生一個句子，並將之顯示在警示告對話方塊中。接著，Script設定新的值來改變Img的width和height屬性設定值。所以交談窗會顯示新的圖片width和height的值， 如圖7-2所示。

在Internet Explorer中，所有的HTML屬性在物件模型中也有相對的屬性：例如：WIDTH屬性和width屬性相對，SIZE屬性和size屬性相對。以一對一的對應方式存在。但是物件模型包括很多額外的屬性，是HTML標籤屬性所沒有的。下面這個列表，是一些使用在物件模型中的屬性範例：

background           href
borderColor          innerHTML
cellPadding          pixelHeight
color                src
Display              tabIndex
fileCreatedDate      visibility
fontFamily           z-Index

附錄C 有Internet Explorer支援的標準屬性完整列表，所有屬性的完整描述及可套用的物件，都可以在SBN Workshop網站及書附光碟中找到。在光碟中請參考Workshop(References) 的HTML檔案下﹔DHTML，HTML & CSS﹔DHTML References﹔Properties。若要檢視線上的版本，請連上在5 msdn.microsoft.com/resources/schurmandhtml.htm 的MSDN線上資源網頁。或開啟書附光碟中的MSDN_OL.htm， 然後選擇DHTML properties。

雖然所有的屬性都可以透過腳本語言來讀取，但並不是所有的屬性都能進行寫入的動作。所以並不是所有屬性，都可以即時透過腳本語言來改變。不像width和height屬性在程式7-1中，可以被Script改變。舉例來說，IMG物件的filesize屬性以位元組來計算來源圖檔的大小。因為這個屬性是基於一個實際的數值，所以瀏覽器不能控制它 (因為瀏覽器並不是圖形編輯程式)。即使能透過腳本語言，改變這個數值可能也沒有什麼意義。此外，不同瀏覽器能改變的屬性亦不太相同。Internet Explorer版本4或以後版本，可改變許多顯示在畫面上的元件顯示方式，例如：可改變目前網頁中的圖形的寬度。Internet Explorer 3或較早的版本，及所有目前的Netscape版本大都不能改變這類的屬性。

Note

Internet Explorer 5可讓你監控物件屬性是否作過改變。這是透過一個新的onpropertychange事件和該事件物件的propertyName屬性所完成的， 事件和事件處理將在本章稍後介紹。

表示法和命名方式

當撰寫Script時，用句點分格物件及屬性方法，讓您清楚且方便了解參考的物件和元件。在這個命名慣例中，物件的名稱和它的屬性、集合、子物件名稱都用一個點(一個區隔符號) 來分隔。window.document.linkcolor敘述參考到文件物件的linkcolor屬性，它是window物件的子物件。當使用此表示法時，不一定需要使用完整的名稱，舉例來說，如果您的Script程式所操作的物件在同一個視窗中，通常可以將window物件的名稱省略，因此document.linkcolor表示參考到同一個視窗中document的linkcolor屬性。6

使用JScript時，大小寫是有差別的。為了讓物件模型的元件能正常運作，您的程式必須使用正確的大小寫，舉例來說，我們不能利用Img1.HIEGHT設定程式7-1中img1的height屬性，因為height屬性名稱必須是小寫。一般情況來說，若屬性名稱只由一個英文字 (如src或height)，您應該將屬性、方法、和集合名稱設定為小寫，若由多個英文字，則會混合使用大小寫 (如fileSize或fileModifiedDate) 。

建立擴充屬性

Internet Explorer 4及以後的版本支援一些特殊類別的屬性，稱之為擴充屬性(Expando Properties)。這是使用者建立的屬性，所以無法對映到物件原有的屬性。舉例來說，接下來的幾行script程式碼將建立Img1的一個新的屬性， 這個新的屬性稱為AssociatedText，此屬性的設定值為 "This book covers JScript"：

Img1.AssociatedText = "This book covers JScript"

您可以用一個新的屬性來設定圖形的相關資訊，舉例來說，若Img1是書中的一張圖片，擴充屬性就是有關於本書的敘述。擴充屬性可以在任何時刻被讀取和更改，當建立了擴充屬性時，可以使用不同的命令慣例。例如：我們將屬性名稱的第一個字母變成大寫，便可分辨哪一個是擴充 (Expando) 屬性，哪個是內建屬性。

捕捉事件

正如您在7 第5章 和 第6章 所看到的，當某些動作發生時，在物件模型中的某物件會觸發特定的事件，舉例來說，在一個表格中的INPUT按鈕，當它被按下鈕時，會觸發一個onclick事件，當錯誤發生時，window物件會觸發一個onerror事件。 附錄C 提供了一個Internet Explorer支援事件的完整列表。所有事件完整的敘述可以在SBN Workshop網站和書附光碟中找到。在光碟中請打開Workshop (References) 檔案，參考其下的：DHTML，HTML & CSS﹔DHTML References﹔Events。而線上版本請連至MSDN線上資源網頁( msdn.microsoft.com/resources/schurmandhtml.htm8 )，或開啟書附光碟中名為MSDN_OL.htm檔案，然後選擇DHTML Events。

Netscape Navigator和Internet Explorer同時支援一些常用的事件，這些事件包括：onclick，ondbclick，onmousedown，onmouseup，nmousemove， onmouseover，onkeypress，onkeydown，onkeyup，和onresize。Netscape Navigator有個特別的地方，那就是很精確的規定不同物件所支援的事件，例如在Navigator 4中支援onclick的HTML元件是document、A、INPUT (button、checkbox、radio、rest和submit類型)。此外，很多元件只支援某一個特定的事件，而不支援其他的相關事件。例如，Netscape Navigator在表格中的INPUT按鈕支援onclick不過不支援onmouseover。Internet Explorer幾乎在所有物件上，都支援大部分事件 (特別是常見的事件，例如像是滑鼠事件)。

除非有回應事件的腳本Script程式，不然事件發揮不了實際作用。這種Script程式被視為事件處理程式 (Event Handler)，程式碼7-2是一個利用Script來處理特定事件的標準方法，也就是捕捉事件的方法。

<HTML>
<HEAD>
<TITLE>Listing 7-2</TITLE>
</HEAD>
<BODY onload="alert('BODY loaded.')">
<FORM>
<INPUT TYPE="button"
  VALUE="Click Me"
  onclick="alert('You clicked the button.')"
  onmouseover="alert('You moused over the button.')">
</FORM>
</BODY>
</HTML>
程式7-2

最容易的事件捕捉方式就是使用嵌入的 (也稱之為行內的in-line) 事件處理程式 (正如您在程式列表6-4中所看到的)，在程式列表7-2中，一個事件處理程式嵌入在 <BODY> 和 <INPUT> 標籤中。行內事件處理程式是最廣泛被支援的事件處理程式，過去的幾年瀏覽器也提供部分支援。當載入本文後按鈕被按下時，Netscape Navigator和Internet Explorer都將顯示一個警示對話方塊，但是當滑鼠移到按鈕上方時，Netscape不會顯示警示對話方塊，原因前面已經講過了 (若您覺得第一個警示對話方塊會干擾到你按鈕，您可以按下Enter來關閉警示對話方塊)。

下面的程式列表7-3展示三個常用的方式來捕捉事件，但不是所有方法瀏覽器都支援到。圖7-3到7-7是Internet Explorer程式碼如何運作。圖7-8是Netscape Navigator如何處理在網頁本文中按鈕事件。9

<HTML>
<HEAD>
<TITLE>Listing 7-3</TITLE>

<SCRIPT LANGUAGE="JavaScript">
// If using NS 4+ capture click events (unnecessary in Internet Explorer)
if (window.Event){
  document.captureEvents(Event.CLICK)
  document.onclick=EventInfoNS      // Bind the EventInfoNS function
}
else{document.onclick=EventInfoIE}  // Bind EventInfoIE to a click for IE
function EventInfoIE(){
  // Display what fired the event, its name, the event type, and where
  e=window.event
  alert("The "+e.srcElement.tagName+" element called 	"+e.srcElement.id+
    " fired the "+e.type+" event. This occurred at screenX="+
    e.screenX+" and screenY="+e.screenY+".")
}

function EventInfoNS(e){
  // Display what event happened where
  alert("A "+e.type+" occurred at screenX="+e.screenX+" and screenY="+
    e.screenY+".")
}
</SCRIPT>
<SCRIPT FOR="Span1" EVENT="onmouseover" LANGUAGE="JScript">
  // This code runs when the mouse travels over the SPAN
  Span1.innerHTML="You moused over this."
</SCRIPT>
</HEAD>
<BODY ID="theBody">
<IMG ID="Img1" SRC="circle.gif">
<SPAN ID="Span1" onmouseout="this.innerHTML='You left it.'">
  This is the first state.
</SPAN>
</BODY>
</HTML>
程式7-3

圖7-3 在Internet Explorer中一開始的視窗像這樣，但是當您移動滑鼠或按鈕，它會引發不同事件

圖7-4 當您移動滑鼠到SPAN元件中的文字時，會引發onmouseover事件，文字也會改變

10
圖7-5 當您移動滑鼠離開文字時，會引發onmouseout事件並再次改變文字

圖7-6 在Internet Explorer中，一個警告對話方塊指示IMG物件被按下了

圖7-7 在Internet Explorer中，當在文字上按鈕時， 顯示一個不同的警告對話方塊

圖7-8　這是在文件內按鈕後，Netscape Navigator視窗的內容11

程式列表7-3使用JScript註解 (以兩條斜線 '//' 開始的幾行)。註解非常有用，並建議對每段程式碼的用途加上註解。

如下所示，事件處理程式碼被嵌入在 <SPAN> 標籤中：

<SPAN ID="theSpan" onmouseout="this.innerHTML='You Left it.'">

這段程式碼指定了onmouseout事件，然後將 "this.inner.HTML='You Left it" 結合至那個事件。關鍵字this參考到目前的物件，在本例中就是theSpan。因此不論滑鼠是否遠離SPAN元件，物件的innerHTML屬性設定成You Left it這段文字。因為這個屬性指定了SPAN元件內的顯示內容，所以當滑鼠移到此物件上時，將會看到螢幕上相對的變化。雖然Netscape也支援內嵌式的事件處理，但當滑鼠指標移離SPAN元件時，事實上它將不會做任何動作。這是因為它的SPAN元件並不支援onmouseout或onmouseover，同時也不支援改變innerHTML屬性。

另一個擷取事件的方法，是建立一段只單獨專用於某事件的script程式。如我們在程式6-3及程式7-3的第一段script程式中，此段script程式由一個標準 <SCRIPT> 標籤及包含一個FOR屬性，它是用來設定要被偵測的物件，而EVENT屬性則是設定要被處理的事件。此外，所有SCRIPT標籤都需要加入一個LANGUAGE屬性。

<SPAN FOR="theSpan" EVENT="mouseover" LANGUAGE="JavaScript">

當名稱為the Span的物件遇到一個onmouseover事件時，此段Script程式指令將被執行，當執行這段程式碼時，移動滑鼠指標到顯示文字的SPAN元件上，文字會改變成You Moused over this (如圖7-4所示)。這個擷取事件的方式只有Internet Explorer支援。12

您也可以利用函式來擷取事件，在Netscape Navigator和Internet Explorer都同時支援這種方法，不過兩者之間還是有些不一樣的地方。要利用函式來完成工作，網頁必須包含有名字的函式 (我們在第6章中介紹過函式，我們在第9章會講得更詳細)。舉例來說，程式列表7-3包含兩個函式稱為EventInfoNS和EventInfoIE。

在Netscape Navigator中，您首先必須告知瀏覽器，您想利用captureEvents方法來擷取onclick事件。所以我們先檢查使用的是否是Netscape Navigator，然後擷取click按下按鈕的事件，然後利用下面的程式碼將EventInfoNS函式連結至該事件。

if (window.Event) {
    document.captureEvents(Event.CLICK)
    document.onclick=EventInfoNS
}

if敘述是用來確定是否window物件有一個名為Event的子物件(在第9章您將會找到更詳細的if敘述的說明)，這只在Netscape Navigator版本4和更新版本找得到(在Internet Explorer有一個相似的event，e是小寫的e)， 如果window物件包含這樣的物件，click事件就可被擷取，接著EventInfoNS函式連結至該事件。

在Internet Explorer中，直接就可以擷取到事件，因為幾乎所有的事件都可被自動擷取。事實上，由於Internet Explorer不支援captureEvent方法，所以會造成Internet Explorer的錯誤，這是為何要執行前段的測試之原因，不論何時在Internet Explorer中的document物件中onclick事件被觸發時，下面這段程式會讓EventInfoIE函式被執行：

document.onclick=EventInfoIE

注意連結一個函式到一個事件的語法，在不同瀏覽器之間是相同的。13

我們來細看一下在程式列表7-3中的EventInfoIE函式，這個例子是使用在Internet Explorer中。程式列表包含下面的程式碼， 顯示一個包含元件被按鈕等資訊的警示對話方塊。

e=window.event
alert("The "+e.srcElement.tagName+" element called "+e.srcElement.id+
  " fired the "+e.type+" event. This occurred at screenX="+
  e.screenX+" and screenY="+e.screenY+".")

在Internet Explorer中的window物件有一個子物件名為event， 它只存在當事件發生時 (即只發生在事件發生期間)。我們一開始設定這個物件給名為e的變數，這個步驟不是必要的，不過這會使稍後程式中參考物件變得更容易，且比每次要設定整個階層的物件名稱來得快得多，這個事件物件有許多有用的屬性，舉例來說，它的srcElement屬性可設定哪個特定的物件所觸動的事件。

上面所講用來警告的程式碼，使用srcElement來取得觸動事件的標籤型態、標籤名稱、被觸動事件型態的資訊。事件物件的其他屬性，可以提供一些額外資訊，例如滑鼠在螢幕上的位置 (ScreenX和ScreenY)，滑鼠相對於瀏覽器視窗的左上角位置 (ClientX和ClientY) 和辨別按下哪些按鍵，您可以在網頁上任何位置，在圖形上，在文字，甚至在空白的背景區域上按滑鼠鈕，您就可以看到此函式的運作。注意：雖然onclick事件使用範圍在document物件中，警示窗還是會顯示您按下元件的標籤名稱。這是事件沸升的結果，我們將在下一段中解釋。

用於Netscape Navigator中的EventInfoNS函式，使用單一參數e用來代表Event物件。Navigator的Event物件支援許多屬性，包括screenX， ScreenY、type、pageX、pageY、target... 等等，和許多其他的屬性。這個函式將會顯示發生事件型態和在螢幕上發生位置的警告窗。注意此函式只有當本文區域 (非文字或圖形) 被按下時才會被呼叫。

透過物件模型的事件動作

Netscape Navigator和Internet Explorer透過物件模型來作傳遞事件的方式十分不同。就如同14 第5章 所談的，當在Internet Explorer中一個物件發生了一個事件，這個事件會依照物件模型階層結構沸升 (Bubble up)，直到它到達了階層頂點或刻意被取消時。因為document物件比任何在網頁上可看到的物件有更高的階層。任何物件被按鈕都會反映到document物件，因此在document物件中的onclick事件處理程式會對於在任何物件上按鈕做出反應。在這種方式的事件沸升在很多OS和開發環境中，是一個常用而且標準的事件溝通的標準方式。

Netscape Navigator以完全相反的方式處理：事件由物件階層的頂端傳到底端。在頂端事件如程式7-3被擷取，如果您想要事件被更低階層的物件所處理， 您能使用routeEvent和handleEvent方法直接傳送事件，更多相關資訊可在developer.netscape.com網站找到，Netscape物件模型的教學文件可在Webreference.com找到。除此之外，這個網站也可以找到很多有用的文件，包括Netscape Navigator與Internet Explorer的不同物件模型。

有時在Internet Explorer中，您不希望事件沸升到一個物件的父物件。舉例來說，我們可能想要在程式列表7-3中的圖形，對於按鈕的反應不同於網頁上的其他元件。我們可以在程式列表7-3加入image中的錯誤處理程式來完成停止沸升的工作：

onclick="alert('I react differently.');window.event.cancelBubble=true">

圖7-9當按下圖形時的新結果。

15
圖7-9 按下圖形的結果會和圖7-6不同

現在當圖形被按鈕時，它本身內嵌事件處理程式顯示警告後，便將事件的cancelBubble屬性設為True。這會避免事件沸升至父元件。因此document物件將接收不到這個事件，所以不會執行displayEvent函式。但是網頁中其他物件，仍然可以接受onclick事件，因為這些物件並沒有取消事件沸升的機制。

事件沸升機制可以減少許多程式設計的時間，不過可能也會造成使用上的痛苦。使用一個小程式來擷取許多物件的事件，可節省不少程式撰寫的功夫，但物件產生的事件，有時卻會造成不可預期的影響，並可能會造成瀏覽器的混亂。 附錄A 有一些相關的例子及處理方法。

Note

當使用事件沸升時，使用document物件比較好，通常不會使用window物件。因為許多事件都會沸升到document物件，不一定會沸升到window物件。

呼叫方法16

您可以使用Script來呼叫物件的其中一個方法，以觸發特定的動作。在JScript中，一個方法名稱後總是跟隨著一個括弧，如下所示：

window.open()

這行script呼叫window物件的open方法，讓瀏覽器在螢幕上開啟一個新視窗。有些方法在括弧內支援引數 (arguments)，用來修改方法所執行的動作。舉例來說，window.open() 開啟一個新的空白視窗，但這不一定有用。相對的，您也許想將這個新視窗指向一個特殊位置、並包含視窗名稱、設定它的高度、不想包含功能表列...等條件。為了完成這些設定，open方法就需要不同的引數，例如下面的範例：

window.open("http://www.w3.org"，"w3"，"width=40，height=95，menubar=no")

在這個Script中第一個引數設定open將新的視窗位置指向全球資訊網協會 (W3C) 網站。第二個引數給予新視窗名稱 "W3"，同時這個名稱稍後可用在網頁中錨標籤的Target屬性上，且可改變新視窗的目標連結位置。此行最後幾個參數設定視窗長度與寬度，且設定不要顯示功能列。

不同物件支援不同方法，雖然您會發現一些物件所支援的方式有重複。舉例來說，在Internet Explorer中每個HTML元件，包括IMG、 P、 SPAN、DIV、和TABLE，都支援scrollIntoView方法。若一個元件目前在視窗看不到，這個方法會使視窗捲動到看到元件。不過反過來說，也有只被TABLE物件支援的createCaption方法，它可為Table建立一個Caption元件。

window物件支援許多常用的方法。下面提供了這些方法的一些使用範例，目前Internet Explorer和Netscape Navigator都支援這些方法：17

  • alert 引發顯示一個警告對話方塊，包含文字和一個確認鈕。
  • confirm 引發顯示一個確認對話方塊， 包含文字和一個確認鈕及一個取消鈕。
  • close 使用在Script中，用來關閉利用open方式所開啟的瀏覽器視窗。
  • open 開啟一個新的瀏覽器視窗。
  • prompt 引發顯示一個提示對話方塊，包含文字和確認鈕，取消鈕和一個文字輸入欄位。
  • setInterval 倒數指定的時間間隔後，重複執行Script或函式。
  • setTimeout 當經過指定的時間間隔後，引發執行一次Script或函式。18

附錄C 列出了Internet Explorer支援的方法完整列表。方法的完整敘述可以在SBN Workshop網站和書附光碟中找到。在光碟中，請看Workshop(References) 檔案下的﹔DHTML，HTML & CSS﹔DHTML References;Methods。線上版本請連上MSDN線上資源網頁 http://msdn.microsoft.com/resources/schurmandhtml.htm ，或開啟書附光碟中的MSDN_OL.htm，然後選擇DHTML Methods。

使用方法來建立對話框

alert、prompt、和confirm是一些很有用的方法，您可利用這些方法建立對話方塊讓瀏覽器和使用者產生互動效果。Internet Explorer和Netscape Navigator的3.0版本及更新的版本完全支援這些方法。程式列表7-4展示這些類型的對話方塊使用方法，圖7-10到7-13顯示結果：

<HTML>
<HEAD>
<TITLE>Listing 7-4</TITLE>
</HEAD>
<BODY>
<FORM NAME="F1">
<INPUT TYPE="button"
  VALUE="alert button"
  onclick="alert('You clicked the alert button.')">
<P>
<INPUT TYPE="button"
  VALUE="prompt button"
  onclick="document.F1.Text1.value=prompt('Type below'，'Here')">
<INPUT TYPE="Text"
  NAME="Text1"
  SIZE="50"
  VALUE="Click each button， starting with the alert button.">
<P>
<INPUT TYPE="button"
  VALUE="confirm button"
  onclick="if(confirm('Click OK')){alert('Thank you.')}
    else{alert('I said， CLICK OK!!!')}">
</FORM>
</BODY>
</HTML>19
程式7-4

警示對話方塊在螢幕上會顯示一個包含確定鈕的訊息方塊。當您按下在圖7-10中所示的第一個按鈕，瀏覽器會顯示如圖7-11所示的警告對話方塊，您可以按下確定鈕或按下Enter鍵來關閉這個對話方塊。

圖7-10按下3個按鈕中的任一個，都會產生對應的對話方塊

圖7-11一個警告對話方塊

提示對話方塊會要求使用者提供相關資訊。按下如圖7-10所示的第二個按鈕，會執行一段Script開啟一個提示對話方塊 (圖7-12)。它會要求使用者在文字欄中輸入一些文字。使用者鍵入完文字並按確定鈕後，在Prompt按鈕旁文字欄的值會更改成您在提示對話方塊中所輸入的文字。20

圖7-12　一個提示對話方塊

注意第一個引數指定prompt方法在提示對話方塊顯示的提示文字，第二個引數是放置在文字輸入區的預設文字。輸入New Text到文字欄的結果， 可參考圖7-13。

圖7-13　一個確認對話方塊

使用者在確認對話方塊中，可以看到一段文字敘述以及確認鈕及取消鈕。當要求使用者做決定時，這種對話方塊就十分有用。按下圖7-10的第三個鈕，會出現確認對話方塊 (圖7-13)。這個對話方塊被當成if敘述式的一部份。若括弧內的敘述式等於TRUE，則在程式7-4中的if敘述式會顯示一個包含Thank you文字的警告對話方塊。若敘述式為FALSE，警告對話方塊終就會出現對使用者抱怨的文字內容。我們使用confirm方法，來確定對話方塊中按的是確定鈕還是取消鈕。當使用者按確定鈕時，確認對話方塊會傳回TRUE。若使用者按下取消鈕，則會傳回FALSE。因此當使用者遵從指示按下確定鈕時，會得到一個Thank you對話方塊﹔按下取消鈕的使用者，則會得到一個抱怨的文字訊息。

使用集合21

在 第5章 中，我們學到集合是：將物件的相關子項目依序排列起來的群組。舉例來說，Internet Explorer 4、Netscape Navigator 3及更新版本瀏覽器，它們的document物件包含一個名為images的集合，它可參考 (reference) 網頁中所有圖片。在Internet Explorer的document物件中支援all集合，它可參考整個網頁中所有物件。另一個例子是TR列元件的cells儲存格集合，它可以傳回所有在一個特定的表格列中的儲存格。所有Internet Explorer支援的集合列表可參閱 附錄C 。有關集合的詳細描述可以在SBN Workshop網站及書附光碟中找到，在光碟中，請看Workshop (References) 檔案下的﹔DHTML， HTML & CSS﹔DHTML Refrences;Collections。線上資料可連至MSDN線上資源網站 msdn.microsoft.com/resources/schurmdhtml.htm ﹔或開啟書附光碟中檔名為MSDN_OL.htm的檔案，且選擇DHTML Collections。22

因為集合是儲存成數列的形式，您可以利用集合名稱後面加一個指標，來參考到物件串列中的特定項目 (該項在串列中的數字位置)。集合是從零開始 (zero-based) 開始計算順序，在串列中的第一個項目索引為0， 第二個項目的索引值為1， 以此類推。

程式7-5提供您三個使用all集合的例子，以及如何利用images集合達成類似的效果。在圖7-14中，您可看到這個網頁一開始的畫面。圖7-15顯示一個對話方塊，裡面顯示了all集合中所有標籤名稱，及它們的索引數值。在圖7-16和7-17，是利用all集合來改變圖片。圖7-18顯示按下按鈕後，透過images集合來讓圖片改變的結果。

Note

若對集合索引值由0開始，而不是從1開始感到迷惑時，別擔心！很多人一樣也搞不清楚。在程式設計的世界裡，大部分計數都由0開始，就像其他看起來奇怪的寫程式慣例一樣，這是根源於二進位數學運算，也就是計算機運算的基本觀念。想像一個1950年代的程式設計師，要利用一組位元來建立所有可能組合的清單，每個位元不是on就是off。在串列中的第一個組合將所有的位元都off。而在二進位運算中，所有都off代表二進位數的0。第二個組合除了第一個位元外，其餘位元都off，這個組合代表二進位數字1。這就是串列的第一個項目是從0開始算起的原因。不過你也不用太失望，你將會發現適應這種計數系統其實很簡單。

<HTML>
<HEAD>
<TITLE>Listing 7-5</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function doIt(){
  if (document.all){
    alert("First let's get a numbered list of all page elements.")

    strTagList=""
    for(i=0; i<document.all.length; i++) {
      strTagList+=(i+"\t"+document.all(i).tagName+"\n")
    }
    alert(strTagList)
    alert("Now change the second IMG using absolute index.")
    document.all(6).src="square.gif"

    alert("Finally， change the third IMG using relative index.")
    document.all.tags("IMG")(2).src="square.gif"
  }
}
</SCRIPT>
</HEAD>
<BODY>
<IMG SRC="circle.gif">
<IMG SRC="circle.gif">
<IMG SRC="circle.gif">
<FORM>
Use the all collection.
<INPUT TYPE="button" VALUE="Go" onclick="doIt()"><BR>
Use the images collection.
<INPUT TYPE="button" VALUE="Go" 	onclick="document.images[1].src='x.gif'">
</FORM>
</BODY>
</HTML>
程式7-5

圖7-14　在沒有任何改變之前的Internet Explorer視窗23

當第一個按鈕被按下之後，它的行內 (inline) 事件處理程式呼叫doIt函式。此函式首先測試看看是否all集合存在，且當它存在時才能執行。這是因為若您直接使用all集合，Netscape Navigator及早期的Internet Explorer可能會有錯誤。若它存在，會顯示一個警告對話方塊，說明要產生一份包含目前網頁中所有元件的數字串列。當使用者按下確定鈕，函式利用一個for迴圈來巡行整個all集合，列出它們的標籤名稱，與每個元件在集合中的位置 (它的索引值)。然後將結果傳給strTagList變數 (在 第9章 中，將可學習到更多for迴圈﹔並在 第8章 學習檢視變數及 \n之類的格式化工具)。for迴圈由0開始，到document.all.length為止。length是用來指示all集合中共有多少元件的屬性。最後strTagList的變數值，會顯示在一個警告對話方塊中，如圖7-15所示。

圖7-15　這個警告對話方塊列出每個網頁元件和它的索引值24

當使用者按確定鈕時，會顯示一個新的警示對話窗，提醒使用者第幾個圖會改變，一旦使用者在這個新的交談窗中按確定鈕時，圖形參考all集合的索引值。因為標籤串列指出 (請參閱圖7-15)，第二個圖在串列中是第6個位置，因此我們可以使用document.all(6) 的表示式來代表此物件，稍後我們將使用此方式來改變圖片的src屬性，進而改變顯示的結果，如圖7-16所示。

另一個指向all集合中特定項目的方法，就是利用同一標籤類型的相對位置。all集合的tags方法傳回特定名稱的另一個集合。我們可以使用這個方法來取得一個所有IMG標籤的集合，然後改變這個新集合的第三個項目：

document.all.tags("IMG")(2).src="square.gif"

圖7-16　all集合只是用來改變在索引值6的項目(第二個圖)，下一步第三個圖要改變了

因為集合是以零開始的，第三個圖形是位於IMG標籤集合中的索引2。您可以在圖7-17看到這個程式的特效。

另一個在Netscape Navigator 3和Internet Explorer 4及更新的版本中常見的集合，就是document.images。這基本上是一個已存在的集合，它和在Internet Explorer中的document.all.tags("IMG") 所傳回的集合相同。圖7-18顯示按下網頁中第二個按鈕所得到的效果，它會使用images集合改變其中一個圖像。這個按鈕在兩種瀏覽器中都有同樣的效果。25

圖7-17 　使用all集合的標籤方法來改變第三個圖形

圖7-18　使用images集合來改變第二個圖形

本章將焦點放在如何用Script與物件模型互動。接著我們將只討論純粹的script。下一章中將解釋JScript的資料型態，及如何使用處理這些資料。

實戰Dynamic HTML網站技術 視窗縮放
物件導向式的Scripting 技術


實戰Dynamic HTML網站技術=>資料處理

資料處理
小
工
具 加入書架
加入書籤
上一章
下一章

程式設計的基本目的，就在於能操作或顯示資料，在Internet Explorer 5中的腳本語言 (VBScript和JScript) 就是設計用來在網頁上完成這些目的工具。本章將說明如何在JScript中處理變數，資料，及操作資料的工具等。

變數

嚴格來說，變數並不是資料。然而變數與資料操作完全密不可分，幾乎不可能只談到其中一個而不去談另一個。一個變數是指向或包含資料的物件。事實上，您可以將變數想成是一個容器。舉例來說，下面此行將值2設定給變數名稱為myVar的變數,

myVar = 21

您也可將一個變數設定成另一個變數的值。在下一個例子，變數num1將值設定為50。另一個變數，名稱為num2，將值設定為變數num1.

num1 = 50
num2 = num1

第二個變數的值，num2，現在是50.

因為JScript是一個區分大小寫的語言，您必須小心使用變數，舉例來說：num1、Num1、和NUM1、是三個名稱不同的變數，如果我們在上面的例子設成num2=Num1，便會產生錯誤，因為我們的變數是設定成num1，不是Num1。

變數這個名字的由來，就是因為包含在變數內的值會改變。在下面數行程式碼中，myVar 的設定值會改變三次。

myVar = 10
myVar = someOtherVar
myVar = 75

在這些操作之後，myVar的最後值為75。2

宣告變數

許多的程式語言，要求程式設計師在使用變數之前先建立或宣告變數。如果試著去使用一個尚未宣告的變數，可能會造成程式無法執行。但JScript通常不需先宣告變數，但是先宣告變數是個好習慣。宣告變數要使用var關鍵字。下面的例子宣告兩個變數：myVar和anotherVar，然後設定一個初值為50給anotherVar (這個過程被視為初始化變數)。

var myVar
var anotherVar = 50

JScript中唯一您必須宣告變數的時候，就是建立區域變數的時候。區域變數只能在變數宣告所在的函式內部使用。區域變數有助於降低記憶體的浪費且可提高效率，明確地宣告(explicitly declaring) 變數，也可以使您的程式更容易除錯。若沒有明確地宣告變數，或在函式外宣告變數，這會被稱為全域變數 (globe scope)。它可以在程式的任何部分，利用程式碼來做存取。

資料類型

在JScript中，變數中的資料屬於以下6個資料類型：字串(string)、數值 (number)、布林代數(Boolean)、空值 (Null)、未定義(Undefined)、和物件 (Object)。每個資料類型符合一種特定的需求。和大多數程式語言有些不一樣，JScript的資料型態並不固定，這個意思是說，在JScript中一個相同的變數可以有時包含字串資料，另一時候包含數值資料。下一段將詳細來看看各個變數類型。

字串資料類型3

一個字串是一連串的字元，它可以包含字母、數字、和符號。一個字串利用單引號或雙引號與周圍的程式碼分隔。舉例來說，下面兩行程式碼是相當的，並且設定相同的設定值。

myVar = "This is a string"
myVar = 'This is a string'
Note

我們現在來定義一些基本的術語：一個字元(Character) 是任何字母、數字、或符號﹔字母是指26個字母之一 (大寫或小寫)﹔一個數字是一個或多個位數的數字，且一個符號是指非字母，非數字的字元，例如：音標。

在JScript中的字串由unicode字元所組成。Unicode中，定義了各國數以千計的字元。一個字串可以是百萬個字元長。不過使用這種unicode字串的script速度會很慢。

如您將單引號及雙引號同時包含在字串本身裡面時，可利用一組對稱的引號來定義字串。舉例來說，下面這行程式碼設定字串值為He said，"Hello!" 給變數myVar：

myVar=' He said，"Hello! " '

您也可以使用跳脫代表字元 (Escape sequence) 來代表引號或其他字元。跳脫代表字元就是一個字元的特殊碼而已，使用跳脫代表字元通常有兩個目的：4

  • 為了表示字元當成內容的一部份，而不是當作字串的處理符號 (舉例來說，當您想要雙引號當作字串的一部份，但是字串目前又被括在雙引號中)。
  • 為了加入沒有相等的字元的控制字元，例如一個換行符號 (carriage return)。

字元 | 跳脫字元
單引號 | \'
雙引號5 | \"
反斜線 | \\
倒退 | \b
游標回行首 | \r6
換頁 | \f
換行 | \n
水平定位 | \t

下面這行程式碼使用了一些跳脫字元：7

myVar="Here are some special characters - \\,\",\'."

而變數myVar的字串內容就是Here are some special characters - \,",'。

NOTE

除了在JScript支援跳脫字元外，瀏覽器可以透過字元代碼 (Character Entities) 顯示外國語言字母、特殊字元、及符號。舉例來說：字元代碼 代表一個沒有斷行 (nonbreaking)的空格。您可以在SBN Workshop網站和書附光碟中，找到有關字元代碼的資訊。在光碟中，請看Workshop(References) 檔案下的﹔DHTML，HTML，HTML & CSS﹔HTML References﹔Character Sets。線上版本請連至MSDN線上網站 http://msdn.microsoft.com/resources/schumandhtml.htm ，或開啟書附光碟MSDN_OL.htm，然後選擇Chracter Sets。

數值資料類型

在JScript中，資料可表示成整數 (例如:2) 或浮點數 (數字中含有小數點，如54.686) 的型態。這些數字一般都以10進位的方式表示 (就是一般的標準10進位數字)，但它們也可以表示成科學記號、或改成用8進位、16進位來表示數字。下面幾行的Script，使用許多不同的表示法來表示一個數字：8

varInDecimal=46
varInScientific=4.6e1
varInOctal=056
varInHexadecimal=0x2e

上面每個變數都是46 (您可以在Microsoft Developer Network (MSDN) 中找到完整的數值類型的解釋)﹔或選擇連上MSDN線上資源網頁 http://msdn.microsoft.com/resources/schumandhtml.htm ，也可直接在書附光碟中開啟MSDN_OL.htm，然後選擇JScript Data Types)。

許多語言有許多不同的資料類型來代表資料。在這些語言中，您必須先指定變數是整數值或是浮點數值類型，而且變數只能儲存指定資料類型的資料。但JScript只提供一個數值類型，且它可以放置兩種類型的數值資料。也就是說，一個變數可以一下子包含整數，另外一個時候包含浮點數。

除了一般數值，變數還有其他的型態，如表8-1所示：

表8-1　數值類型的變數之特殊值9
變數 | 設定值
Infinity | 無限大，在數學運算中視為正無限大.
+Infinity | 明顯的正無限大，在數學運算中視為正無限大
-Infinity10 | 負無限大，在數學運算中視為負無限大
+0 | 正零，將此一般沒有正負號的數值設為正號
-0 | 負零，將此一般沒有正負號的數值設為負號
NaN | 非數值，此值可能是被設定出來的，或是數學運算的結果，例如: -Infinity除以 +Infinity的結果是NaN11

布林代數資料類型

布林資料只能有兩種可能值，True或False。在很多的C和C++ 中，布林代數的值是利用0為False，1或非零的數字為True來做模擬。但是JScript提供一個真正的布林資料類型。布林代數最常用於執行測試，並決定是否發生一個動作。舉例來說：您可以設定一個條件式敘述，若執行結果得到的布林代數為True則執行一個動作，若為False，則執行另一個動作。我們在第9章中，將會繼續討論布林代數與條件式敘述的使用方式。

Null資料型態

Null資料型態同時具有數值及資料型態的特性。將一個變數設定成Null表示該變數沒有數值﹔也同時表示此變數並不屬於其他資料類型 (例如：字串或數字)。下面這一行程式，設定一個Null值給變數myVar：

myVar = Null

注意一下，雖然Null在JScript是一個資料型態，不過在其他語言中不一定是如此，而可能Null單純等於0。這個資料型態最常使用在錯誤處理，例如當作未定義的資料。

未定義的資料類型12

未定義 (undefined) 資料型態是一個特殊的型態，不能將變數設成這個值。另一方面，如果一個變數沒有宣告，或是宣告過沒有設定值，此變數就會被視為是undefined的資料型態。如果您使用到一個之前尚未設定數值的變數，會常看到一個寫著變數是undefined的錯誤訊息。例如：若var2之前尚未定義與設定數值，var1=var2此行會產生 'var2 is undefined' 的錯誤訊息。

程式8-1使用了到目前為止所討論過的資料型態，圖8-1是執行後在瀏覽上顯示的結果。

<HTML>
<HEAD>
<TITLE>Listing 8-1</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var a="\"word\""
var b=32
var c=true
var d=null
var e
document.write("a="+a+", b="+b+", c="+c+", d="+d+", and e="+e)
</SCRIPT>
</HEAD>
</HTML>
程式8-1

圖 8-1　顯示不同的資料類型

在程式列表8-1和圖8-1中，變數a是一個字串值、b是一個數值、c是個布林代數值、d設定為Null，e沒有給值。注意加號在document.write開頭那一行中，不同字串利用加號連接起來，建立一個更大的字串，此字串接著就會利用document.write() 的方式，將結果標準HTML的方式顯示在螢幕上 (稍後本章，我們將會討論使用加號和其他運算元)13

物件資料類型

最後一個要介紹的JScript資料型態就是Object，這個項目包含了許多不同的種類，變化也很多。舉例來說，陣列物件讓您能組合零散的資料﹔日期物件中，可以儲存日期和時間。您也可以藉由將Object Model的物件指定給JScript的方式，設定自己的物件。程式8-2就是設定物件數值的方式，圖8-2是顯示的結果。

<HTML>
<HEAD>
<TITLE>Listing 8-2</TITLE>
</HEAD>
<BODY>
Here is a text input.
<FORM NAME="F1">
<INPUT NAME="T1" TYPE="text" VALUE="foo">

<SCRIPT LANGUAGE="JavaScript">
  a=document.forms[0].elements[0]
</SCRIPT>
<INPUT TYPE="button" VALUE="Display Value" 	onclick="alert(a.value)">
</FORM>
</BODY>
</HTML>
程式8-2

圖 8-2 存取物件的方式，按下 Display Value 按鈕會顯示您輸入的文字

在程式8-2所示的Script程式中包含一個表格，然後裡面有一個文字輸入的欄位。這個文字欄，就是一個在物件模型中的物件。我們利用a=document.forms(0). element(0) 這段程式，設定文字欄物件給JavaScript的變數a後，用a就可以代表文字欄位了。這樣不但容易了解，也方便修改。若物件重複被使用很多次，Script的執行速度也會相對的增加。所以a.value現在就代表文字欄物件的value屬性。當按下Display Value鈕時，瀏覽器就會顯示文字欄位的value屬性的設定值。還可進一步改變文字欄的內容後再按Display Value鈕一次，瀏覽器會顯示剛剛更新的文字欄內容。14

您可以使用new運算子，在JScript中建立自己的物件。物件製作出來後，使用起來就像是物件模型內建物件一樣，你可為這些物件設定自己的屬性和方法。在程式8-3中，建立一個物件及其屬性值，圖8-3可看到瀏覽結果。

Note

Document物件有一個集合稱為forms，它可參考到目前文件中所有的表單元件。在這個集合中每個項目，依次都有一個稱做elements集合，它只是簡單代表表單中的所有元件 (INPUTs，SELECTs，等)。在本例中利用物件名稱document.forms[0].elements[0] 來指向物件，是最常見且跨瀏覽器/平台/版本的方法。若只需要在Internet Explorer 4或更新版本下工作，那麼使用Internet Explorer的進階物件模型a=F1.T1敘述，就可以完成設定工作。

<HTML>
<HEAD>
<TITLE>Listing 8-3</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var Stu1=new Object
Stu1.name="John Doe"
Stu1.test1="B+"
Stu1.test2="A-"
document.write("There is an object called Stu1<BR>")
document.write("It's name property equals "+Stu1.name+"<BR>")
document.write(Stu1.name+"'s score on test1: "+Stu1.test1+"<BR>")
document.write(Stu1.name+"'s score on test2: "+Stu1.test2+"<BR>")
</SCRIPT>
</HEAD>
</HTML>
程式8-3

圖8-3　建立一個物件

利用程式8-3中var Stu1 = new Object敘述，我們就可以建立一個Stu1物件。接著我們會將Stu1物件的屬性name1、test1、test2，分別給予一個設定值。之後我們可以使用Stu1物件的這些屬性，來修改這些值。15

建構元函式

JScript支援使用建構元函式 (constructor functions)，它可以輕易地建立一群您所定義的物件。下面程式會是一個建構元函數，用來建立在程式8-3的物件：

function makeStudent(StrName, strTest1, strTest2){
  this.name=strName
  this.Test1=strTest1
  this.Test2=strTest2
}

可以利用下列此行程式來建立物件實體：

Stu1=new makeStudent('John Doe','B+','A-')

可以輕易的建立相同的物件，如下所示：

Stu2=new makeStudent('Alexendar To','A+','B-')
Stu3=new makeStudent('Calvino Hsu','B+','A')
Stu3=new makeStudent('Kitty Hsu','A','A+')16

陣列物件

陣列物件可以當程式一連串相關的資料集合，每份資料都是陣列的一個元件，並且擁有一個相對的索引數字。陣列索引值是從0開始計算 (zero-ordered)。您可以用陣列名稱後面加上中括號括住的元件索引值，來指向陣列中某一物件的位址。因此，在myArray陣列中您可以使用myArray[0] 來指向到陣列中第一個項目﹔若要指向第二個項目，則可寫成myArray[1]。您可以如程式8-4所示，使用new運算元來建立一個陣列並設定它們的資料，結果顯示在 圖8-4。

<HTML>
<HEAD>
<TITLE>Listing 8-4</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var nameList=new Array
nameList[0]="John"
nameList[1]="Mary"
nameList[49]=3774
document.write("The first value is "+nameList[0]+"<BR>")
i=49
document.write("The value at index "+i+" is "+nameList[i]+"<BR>")
i=25
document.write("The value at index "+i+" is "+nameList[i]+"<BR>")
</SCRIPT>
</HEAD>
</HTML>
程式8-4

圖 8-4　使用陣列

在JScript中，一個陣列的每個元件可以包含不同資料型態。注意程式8-4的陣列中，同時包含字串與數字。陣列也不需要在每個索引位置上都必須有元件。這就是為什麼我們在程式8-4中跳過索引1到49的元件。被跳過的元件會被定義成undefined的值。17

Note

陣列和物件在JScript中是相似的，事實上，您可以使用文字來當作陣列的索引名稱，而不使用數字－例如:

nameList["name1"]="John"

設定完後，您可以利用陣列表示法 (nameList["name1"] 或通常用於物件的標準表示法(nameList.name1) 來表示這個元件。

變數與資料處理

現在您已經大概了解變數和資料的概念，但是我們還是需要知道如何使用這些變數及資料。基本上來說，操作資料有兩個基本工具：就是運算元 (Operators) 和方法 (Methods)。

運算元 (Operators)

你可以利用JScript建立數學運算式。一個運算式基本上就是一個數學運算的句子，例如：5+6或myVar+40 。而運算元就是句子的動詞，用來執行一項動作。在5+6這運算式中，加號運算元執行將兩個數字加起來的動作，表8-1中是常見的數學運算元：18

表8-2 　常見數學運算元
運算元 | 執行動作
= | 設定一個值或敘述式給一個變數，例如: myVar = 6設定數值6給變數myVar
+ | 加法或字串連接，將兩個數值相加或兩個字串連接起來。例如:1 + 2等於3，及 "sample"+"text" 等於 "sampletext"19
- | 減法，從一個數值中減去一個數值
- | 單一存在的負數，讓所相連的值變成負值，例如: -3就是 "負的3"
/ | 除法，一個數值除以另一個數值
*20 | 乘法，一個數值乘以另一個數值
% | 取餘數，傳回一個數字除以另一個數字所剩的餘數，如7%4為3
+=,-=,*=,/=,%= | 算是運算設定。執行一個變數內容的操作，然後將操作結果回存變數中。如果變數myVar值為5，myVar+=6式子，會將變數加6;結果現在myVar的數值就等於11。因此myVar +=6相當於myVar= myVar+6。當使用在字串上，+= 運算元可連接一個字串到另外一個。例如: 若myVar的值為 "sample"，myvar+="text" 會改變myVar的值成為 "sampletext"
++ | 遞增加1，如myVar值為6，myVar++ 會改變該值到7，因此myVar++ 相當於myVar=myVar+121
-- | 遞減減1，如myVar值為6，myVar-- 會改變該值到5，因此myVar-- 相當於myVar=myVar-1
() | 設定成優先計算的數值，用來將運算式的一部份組織成一群，4+(6/2) 運算式由6除2後的結果再加上4，最後結果值為7，相對地，(4+6)/2運算式，則是4加6然後結果除2得到最後結果為5

程式列表8-5使用了 + 運算元。當瀏覽器處理這個程式時，您可以由圖8-5看到瀏覽結果。

<HTML>
<HEAD>
<TITLE>Listing 8-5</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var a=15
var b='abc'
var c='10'
var d=true

document.write("Variable a=15, b='abc', c='10' and d=true<BR>")
document.write("a+10 equals "+(a+10)+"<BR>")
document.write("b+'def' equals "+(b+'def')+"<BR>")
document.write("c+a equals "+(c+a)+"<BR>")
document.write("b+d equals "+(b+d)+"<BR>")
document.write("a+d equals "+(a+d)+"<BR>")
</SCRIPT>
</HEAD>
</HTML>
程式8-522

圖8-5　使用 + (相加，或字串相連) 運算元

第一個數學式為a + 10，因為變數a是15，所以a + 10會將15加上10，結果就是25。下一行中，我們加入字母 "def" 到變數b (一個包含字母abc的字串)，結果得到字串abcdef (換句話說，兩個字串被連接起來了)。

再接下來的三行展示當您試著加入不同資料型態的變數會發生什麼事。當一個字串加入一個非字串時，非字串通常會被先轉換成字串，然後兩個字才會被接起來。例如: c + a運算式中，c是一個包含兩個字元1和0 (10) 的字串，而a數字15，結果會得到字串1015。接下來的一行中，布林代數變數d (設定值為True) 加到字串b (字串值abc) 之後，結果字串值為abctrue (布林代數值先轉換成字串，再與變數b的值相連結)。最後，您可以看到一個布林代數變數如何被加到一個數值型態的變數中。運算式a+d相當15+true。在這樣的運算中布林代數值的True被視為1，且False被視為0，因此，15+True運算式會得到16。

型別轉換

雖然通常JScript會自動在資料型別中轉換，但有時可能你並不希望這樣的轉換發生。有許多內建的方法可控制資料型別的轉換方式，確定最後傳回的資料是想要的資料型態。

您可以使用typeof運算決定變數目前的型態。這個運算元可能傳回6個值：String、number、Boolean、Object、Function和Undefined。程式8-6是typeof的使用方式，圖8-6為瀏覽器瀏覽結果。23

<HTML>
<HEAD>
<TITLE>Listing 8-6</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var a=15
var b='abc'
var c='10'
var d=true
var e=window
var f

document.write("Variable a=15, b='abc', c='10', d=true, ")
document.write("e=window, and f is not equal to anything.<BR>")
document.write("a is of type "+typeof(a)+"<BR>")
document.write("b is of type "+typeof(b)+"<BR>")
document.write("c is of type "+typeof(c)+"<BR>")
document.write("d is of type "+typeof(d)+"<BR>")
document.write("e is of type "+typeof(e)+"<BR>")
document.write("f is of type "+typeof(f)+"<BR>")
</SCRIPT>
</HEAD>
</HTML>
程式8-6

圖8-6　使用typeof運算元

使用isNaN方法是另一個變數或運算式的方法，若此項目不是一個數字 (且不能表示為數字)，則測試會傳回True，若為數字則傳回False。要測試變數或運算式，可將它們用括弧起來，然後放在所呼叫的isNaN方法後面 (把它當作傳入isNaN方法的引數)，因此，isNaN("test") 傳回True，因為 "test" 是個字串，而非數字，isNaN(13) 傳回false。

因為它是個數字。然而isNaN("13") 會傳回false，雖然13 (用雙引號括住) 是個字串，不過它很容易被表示成數字。若變數a的值為13 ，isNaN(a) 運算式同等於isNaN(13)，且傳回false因為13是個數字。

您可使用parentInt方法或parseFloat方法，將一個字串變成一個數字。parentInt方法會將字串中第一個非數字字元後的任何字元去除 (甚至是一個小數點) 除了要保留已存在的小數點之外，parseFloat方法運作方法與parseInt方法相同。一個數字 (或其他資料型態)可利用toString方法來轉換成字串，這是所有標準資料型別中內建的方法。24

程式列表8-7展示在將它們加在一起之前，使用一些處理變數的方法，結果請看圖8-7。

<HTML>
<HEAD>
<TITLE>Listing 8-7</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var a=15
var b='10.5'
var c='12a5'

document.write("Variable a=15, b='10.5', and c='12a5'<BR>")
document.write("isNaN(a) evaluates to "+isNaN(a)+"<BR>")
document.write("isNaN(b) evaluates to "+isNaN(b)+"<BR>")
document.write("isNaN(c) evaluates to "+isNaN(c)+"<BR>")
document.write("a+b equals "+(a+b)+"<BR>")
document.write("a+parseInt(b) equals "+(a+parseInt(b))+"<BR>")
document.write("a+parseFloat(b) equals "+(a+parseFloat(b))+"<BR>")
document.write("a+parseInt(c) equals "+(a+parseInt(c))+"<BR>")
document.write("a+parseFloat(c) equals "+(a+parseFloat(c))+"<BR>")
document.write("a+a equals "+(a+a)+"<BR>")
document.write("a+a.toString() equals "+(a+a.toString())+"<BR>")
</SCRIPT>
</HEAD>
</HTML>
程式8-7

圖8-7　在資料型別間轉換的效果

在程式8-7中，我們在變數b中使用parseInt產生的結果是整數﹔若使用parseFloat，則會得到有小數點的數字。本例中最後一個運算式中我們將一個變數a (是一個數字) 加到表示成字串的a，所以兩個a會以字串的方式連接起來。

Note

您可以用split和join方法，將字串轉換成一個陣列。這些方法可將一個字串，當作引數傳入陣列。myArray = myString.split(",") 這段程式會將myString轉換成一個陣列，且將結果設定給myArray。在第一個逗點 (傳至split方法的引數值) 之前的myString內容，將會設定給myArray[0]，在第一和第二逗點間的內容設定給myArray[1]，以此類推。join的功用和split相反，它將一個陣列中所有的字元，變成中間用逗點分隔字串 (如果join傳入的引數是逗點)。有關這些方法的資訊，可連至Microsoft Developer Network Scripting網站諮詢，您可以先連上MSDN線上資源網站25 msdn.microsoft.com/resources/schurmdhtml.htm 或在書附光碟中開啟檔名為MSDN_OL.htm的網頁，然後選擇JScript Language References。

不同資料型別的方法與性質

每個資料型別都有它自己特殊的方法與性質。正如您記得的，方法是一些可以操作資料的動作，屬性可給我們有關資料的資訊。先前我們討論過，所有資料物件都支援toString方法及valueof方法 (傳回物件的值)。 length是一個很有用的屬性，它會隨著資料型別改變而產生不同的動作。

下一段將會簡介不同資料型別所支援的方法與屬性，您可以在Microsoft Network Scripting網站 msdn.microsoft.com/scripting 找到這些方法和屬性的詳細說明。26

String

string型別的變數使用的方法如下表8-3所示：

表8-3　String變數型別的方法
anchor | FromCharCode | Split
big27 | IndexOf | strike
blink | Italics | sub
bold | LastIndexOf28 | substr
charArt | Link | substring
charCodeAt | Match | sup29
concat | Replace | toLowerCase
fixed | Search | toUpperCase
fontcolor30 | Slice | toString
fontsize | small | ValueOf

這些方法在動態物件架構下，使用的方法是一樣的，且它們也是使用先前討論過的標準表示法。例如：有一個叫做myString的變數，myString.toLowerCase() 會運用toLowerCase方法到myString，將變數myString中的文字字母變小寫。

程式8-8提供一些有用的例子，結果可參考圖8-831

<HTML>
<HEAD>
<TITLE>Listing 8-8</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var a="Fourscore and seven years ago..."
doc=document

doc.write("a is a string equal to <B>"+a+"</B>")
doc.write("<BR>")
doc.write("a.charAt(3) is <B>"+a.charAt(3)+"</B>")
doc.write("<BR>")
doc.write("a.indexOf('and') is <B>"+a.indexOf('and')+"</B>")
doc.write("<BR>")
doc.write("a.lastIndexOf('s') is <B>"+a.lastIndexOf('s')+"</B>")
doc.write("<BR>")
doc.write("a.replace('Four','Two') is 	<B>"+a.replace('Four','Two')+"</B>")
doc.write("<BR>")
doc.write("a.substring(3,12) is <B>"+a.substring(3,12)+"</B>")
doc.write("<BR>")
doc.write("a.length is <B>"+a.length+"</B>")
</SCRIPT>
</HEAD>
</HTML>
程式8-8

在程式8-8中，charAt方法傳回在字串中的特定位置 (索引) 所在的字元。因為字串索引值是由0開始計算，charAt(3) 會傳回字串中第4個字元。indexOf方法會搜尋整個字串，並傳回字串中指定字元或字元組的第一個位置。lastIndexOf方法則是由字串後面開始，搜尋字元或字元組。使用replace方法可以取代字串中的部分字元 (用Two來取代Four )。只要給開始和結束的位置，substring方法可以傳回字串的一部份。利用Length屬性我們可以知道字串的字元數。

圖 8-8　使用不同的字串處理方法

數字與布林代數

數字和布林代數變數只支援toString和valueOf方法，不支援length屬性。32

數學物件

除了toString和ValueOf方法，在JScript中可以利用Math物件來作數字處理。這個物件支援很多方法，可用數學運算上。例如您可以使用pow方法來做次方運算，或cos方法做一個數字的餘弦運算，這裡列出Math物件支援的方法：

abs | acos | asin | atan | atan233 | ceil
cos | exp | floor | log | max | min34
pow | random | round | sin | sqrt | tan

部分方法在程式列表8-9中，下一頁圖8-9是執行的結果35

<HTML>
<HEAD>
<TITLE>Listing 8-9</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var a=2.767

document.write("a is a number equal to "+a+"<BR>")
document.write("Math.cos(a) equals "+Math.cos(a)+"<BR>")
document.write("Math.pow(a,2) equals "+Math.pow(a,2)+"<BR>")
document.write("Math.floor(a) equals "+Math.floor(a)+"<BR>")
document.write("Math.round(a) equals "+Math.round(a)+"<BR>")

document.write("Math.random() equals "+Math.random()+"<BR>")
document.write("Math.random() equals "+Math.random()+"<BR>")
document.write("Math.random() equals "+Math.random()+"<BR>")
</SCRIPT>
</HEAD>
</HTML>
程式8-9

圖8-9　使用數學物件

在程式8-9第一個Math物件是使用cos方法來求變數的餘弦函數值。第二個使用pow方法取得a的2次方，傳回a的2平方值。float方法將所有小數點去除，而round方法則是四捨五入到最接近的整數。每次呼叫random方法時，都會傳回一個介於0與1之間的隨機數字。注意每一次使用random，都會產生不同的數字。

陣列

陣列支援concat，join，reverse，slice和sort方法，您可使用concat方法來將兩個陣列結合為一，join方法會將陣列中的值，建立成一個字串﹔而字串中的每一個值，都會用你所指定的符號一一分開。reverse方法會將陣列中元件反過來排序。slice方法傳回陣列的一部份。sort方法能讓陣列的元件重新排序。length性質傳回陣列中元件的數目，例如：若一個陣列索引從0到9，則它的length為10。但即使在範圍內的陣列值未完全定義 (undefined)，傳回的索引值不會受影響。36

在本章，我們已經知道一些JScript處理資料的方法。下一章中，我們將討論如何利用函式來控制JScript程式的流程。我們會先將Script程式包裝成函式，以方便重覆使用。函式中再加入包含一些條件式，讓您的Script在不同情況下有不同的反應。此外，我們還會討論讓工作能重複執行的迴圈 (loop) 使用方法。

實戰Dynamic HTML網站技術 視窗縮放
資料處理


實戰Dynamic HTML網站技術=>函式、條件式與迴圈

函式、條件式與迴圈
小
工
具 加入書架
加入書籤
上一章
下一章

撰寫程式 (Programs) 的目的，通常是為了要執行一些特定的工作。本章將討論控制程式動作的方法。首先我們會介紹函式，您可以先設定指令的流程，然後一次執行所有操作命令。然後會使用條件敘述，來控制程式執行的條件。最後，我們將會介紹不同的程式迴圈，程式迴圈可以幫助你快速完成重覆的工作。

函式

程式經常需要針對不同的情況，進行一些特定的動作。函式簡單來說，就是一群擁有名稱的程式碼，我們只要呼叫函式名稱，這些程式隨時都可以被執行。我們在 第6章1 學到可以在JScript中利用function關鍵字，後面用一個函式名稱及一組括弧來定義一個函式。這組Script程式必須包含在大括弧 { 和 } 後面則定義這個函式必須執行哪些動作。舉例來說，下面的程式建立一個名為greetUser的函式，它可以顯示一個警告對話方塊。

Function greetUser() { alert("嗨! 這是一個對話方塊! ")}

GreetUser函式可以在任何時候透過它的名稱 (包含括弧) 被呼叫。舉例來說，下面這個BUTTON標籤裡面有嵌入事件處理

程式，當按鈕按下時會呼叫greetUser函式。

<BUTTON onclick="greetUser()"> HELLO </BUTTON>
Note

JScript有一個奇怪的特色，就是函式可以被視為變數 (Variables) 或資料 (Data)。所以使用函式的方法更多，而這些方法在其他程式語言是做不到的。舉例來說，一個函式可以當作另一個函式的引數，或陣列中的索引可以被設定成不同的函式。

引數 (Arguments)2

引數 (Arguments) 放置在函式名稱後面的括弧中，它提供了一種可將資訊傳遞 (引入) 函式的方法。您可以利用逗點將引數隔開，讓多個引數可以傳遞到一個函式中。程式列表9-1展示了一個函式使用兩個引數，在圖9-1中是當您按下的其中一個按鈕之後，瀏覽器的顯示結果。

<HTML>
<HEAD>
<TITLE>Listing 9-1</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function changeIt(target,newText){
  oldText=target.value
  target.value=newText
  alert("The button that read '"+oldText+"' now reads '"+newText+"'.")
}
</SCRIPT>
</HEAD>
<BODY>

<FORM>
  <INPUT TYPE="button" VALUE="Btn1" onclick="changeIt(this,'One')"><BR>
  <INPUT TYPE="button" VALUE="Btn2" onclick="changeIt(this,'Two')"><BR>
  <INPUT TYPE="button" VALUE="Btn3" onclick="changeIt(this,'Three')"><BR>
</FORM>
</BODY>
</HTML>
程式9-1

圖9-1　當一個按鈕被按下後就會出現一個交談窗

在程式9-1中，我們一開始就利用VALUE屬性來設定每個按鈕的文字值。每個按鈕都有一個onclick事件的處理程式，當元件被按鈕時，它就會呼叫changeIt函式。有兩個引數傳遞到changeIt函式: 第一個是關鍵字this (它會傳回現在的物件)，第二個是我們想要取代按鈕的新文字。

這些傳遞引數值都被依照擺放順序，分別設定給函數的target和newText變數，函式首先儲存按鈕的舊設定值到一個名為oldText變數，以供稍後在警告對話方塊中使用。Target變數和newText變數用來改變被按下按鈕上的文字，最後出現警告對話方塊告訴使用者發生了什麼事。3

當我們呼叫changeIt函數並傳遞引數到函式中，第二個傳入的引數外面被引號括住，但是第一個傳入的引數則沒有用引號括住。將引數用引號括住，表示這個引數是一個字串。當傳遞非字串資料類型的引數，例如數字、物件、或變數 (甚至是包含一個字串的變數)，您不須加入括號。在程式列表9-1中第一個傳遞引數就是指向按鈕物件的指標。傳遞指向按鈕的指標後，然後我們就可以直接透過函式的target變數來存取按鈕的屬性。如果我們在this外面加上引號，我們將只是傳遞一個包含t、h、i和s的字串給函式，而非傳遞物件本身。就好像給直接某人一台車，和只告訴他車子的車牌號碼是不一樣的。我們傳遞的第二個引數中，則是要設定給按鈕的文字。

傳回值 (Returns)

您剛剛才看到如何使用引數來傳遞資料給函式。要從函式傳回資訊，您可以使用傳回值 (Return)。return關鍵字可讓我們得到函式計算的結果，也就是當執行函式執行後 "傳回" 一個值給呼叫的程式。您可以使用這種技術，將函式的傳回值給一個變數，或在一些其他方式上使用這個傳回值。程式列表9-2展示了傳回值的使用方法；在圖9-2中，您可以看到這個程式的執行結果。

<HTML>
<HEAD>
<TITLE>Listing 9-2</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function rndNum(maxNum){
  num=Math.random()
  num=num*maxNum
  num=Math.ceil(num)
  return num
}
function tellUser(specifiedNum){
  alert(rndNum(specifiedNum))
}
</SCRIPT>
</HEAD>
<BODY>

Type a number in the area below，then click Calculate.<BR>
The page will generate a random number between 1 and the
number you entered.<BR>

<FORM>
<TEXTAREA NAME="TextNum">10</TEXTAREA>
<BR>
<INPUT TYPE="button" VALUE="Calculate"
       onclick="tellUser(TextNum.value)">
</FORM>
</BODY>
</HTML>
程式9-2

圖9-2　從一個函式傳回一個值4

程式列表9-2說明了一個引數如何傳至一個函式中、及函式之間如何傳遞所需資料，還有return關鍵字的使用方法。當Calculate鈕被按下時首先會呼叫tellUser函式，並將名稱為TextNum的多行式文字方塊的值設定為引數。TellUser函式接著產生一個警告對話方塊。這個對話方塊顯示rndNum函式的傳回值，此函式產生0到1的亂數。然後乘上引數傳遞過來的數字，然後將結果無條件進位。最後結果值傳回tellUser函式，然後顯示一個警告對話方塊在螢幕上。

Note

程式列表9-2應該可以使用在Netscape Navigator或Internet explorer 4或以後的版本。若在版本3的瀏覽器中使用本程式，您不能使用這樣的語法TextNum.value來指向文字區的數字。您可能需要用較舊的語法document.forms(0).elements(0).value來完成相同的目的。另一個瀏覽器之間的不同﹕就是Internet Explorer的INPUT外不需要FORM標籤，且可直接使用BUTTON標籤。

如果設計一個現實世界中需要使用的網頁，還需要做一些錯誤檢查來確保傳遞過去的引數是一個數字。在程式列表9-2中，若輸入非數字的字母或單字，網頁會顯示NaN，這表示傳遞過去的值並非是一個數字。在下一段中，我們將學習有關輸入錯誤資料的檢查方法。

條件式

條件式敘述可設定動作發生前所需符合的條件。條件式一般來說是判斷布林值的邏輯敘述式。在深入探討條件式之前，我們應該先詳細看看布林代數資料和運算式。

布林代數比較

布林代數敘述式只能有兩種值 (True或False)，所以使用在條件式敘述時特別有用。您可經由下面的方式，設定一個布林代數值給一個變數﹕5

myVar = True

在 第8章 中，我們使用數學運算元來撰寫數學運算式；舉例來說，您可以使用加號運算元來撰寫敘述式4+4，此運算式會等於8。所以您也可以使用布林代數的邏輯運算元，例如﹕4= =4運算後就會得到True。

注意在布林代數中的相等敘述式，使用了兩個等號。一個等號是代表設定運算元，它會設定一個值給另一個變數。而相等敘述式是由兩個等號組成，它會測試兩邊的數值，如果數值相同則布林代數值結果為True，若不同則為False。

因此，敘述式4= =5就是False，而敘述式4= =4 就是True。另一個常見的邏輯運算元就是不等於運算元，它用來測試兩個值是否不相同。舉例來說，敘述式4 != 5的值會等於True，因為當4不等於5時，就是True。這些類型的測試都是常見的布林代數、邏輯運算、或條件式運算。表9-1敘述了一些最常用的邏輯運算元。

表9-1　常用的邏輯運算元6
運算元 | 測試方式
= = | 相等，測試此值和另一值是否相同。舉例來說，如果X和數字4相等，下列三個敘述都為true: x = = 4，x = ="4"，和false == false。第二個敘述，當在做比較時，字串4會自動轉換成數字。(詳見 第8章 有更多有關資料轉換的資訊)。
!=7 | 不相等，測試兩個值是否不相等，舉例來說，4!=5敘述就是true，及4 !=4就是false。
< | 小於，測試一個值是否小於另一個值。舉例來說，若x等於4 ，x < 5敘述式是True及x < 3敘述式是False。
> | 大於，測試一個值是否大於另一個值。舉例來說，若x等於4 ，x > 5敘述式 是False及x > 3敘述式是True。
<= | 小於或等於，測試一個值是否小於或等於另一個值。舉例來說，若x等於4，x<= 5敘述式是True，x <=4敘述式是True ，和x <=3敘述式是False。8
>= | 大於或等於，測試一個值是否大於或等於另一個值。舉例來說，若x等於4，x >= 5敘述式是False，x >=4敘述式是True ，和x >=3敘述式是True。
! | 取反值 (NOT)，將布林代數的運算值取相反值。舉例來說，若x相等於True，敘述式 !x相等於false和 !(4 = =5) 會得到True。
&& | 且 (AND)，比較兩個布林運算敘述值。如果兩個敘述值都是True，這個運算元會傳回true，如果都是false，則它回傳回false，舉例來說，敘述式 (4= =4)&&(4<5) 相當為True。如果變數hungry是True，變數havefood是false，而canEat等於hungry&&havefood，則canEat等於false。
||9 | 或 (OR)，比較兩個布林代數敘述式。如果其中一個敘述式是true，運算式會就傳回true；只有兩個都是false才會傳回false。舉例來說，若x相等於4，y相等於5；敘述式 (x = =4)||(y= =4) 會等於true，敘述式 (x= =3)||(x= =4) 等於False。
= = = | 全等，測試是否兩個數值不只相等而且有相同的類型。舉例來說，敘述式4= = =4等於true，但是敘述式4= = ="4" 相等於false (第二個敘述式傳回值為false，因為在全等運算元沒有型別轉換發生) 。
!= = | 不全等，測試兩個數值是否不相等或資料型態不同，或不相等且資料型態也不同。除非兩個值都是相同的型態和擁有相同的值，這個運算式才會傳回true。舉例來說，敘述式4 != = 4相等於false，及敘述式4!= =5，(4!= =5)，和4!= ="4" 都是相等於true (在不全等運算元運算中沒有型別轉換)。

IF…敘述

現在您已經看到如何使用布林代數做運算比較，接著讓我們在一些條件敘述式中，將他們實際運用一下。最基本的條件式敘述就是If …敘述，就像通常在許多語言中使用的If… 敘述。這個敘述設定若遇到一個條件 (若一個值是True)，則會發生一個動作。若值並非True，則這個動作就不會發生。一個If … 敘述以關鍵字If為首，後面接著用括弧括著布林代數敘述式，再接著後面緊接著用大括弧括住一組要執行的動作。下面一段程式碼是一個簡單的if …敘述：10

if (x= =4) { alert("x is equal to four")}

這個敘述一開始就測試看看x是否等於4。若是的話，這段程式碼就會顯示一個對話方塊，裡面會出現 "x is equal to four"。

If…敘述的延伸版本為if…else敘述。這個敘述表示若符合指定條件，則會(then) 發生一個動作﹔否則 (else) 則執行另一個動作。程式列表9-3是由程式列表9-2修改而來。顯示如何使用一個if…else敘述來測試資料錯誤，圖9-3是輸入文字時 (而不是所預期的數字時)，程式所產生的反應。

<HTML>
<HEAD>
<TITLE>Listing 9-3</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function rndNum(maxNum){
  num=Math.random()
  num=num*maxNum
  num=Math.ceil(num)
  return num
}
function tellUser(specifiedNum){
  if (isNaN(specifiedNum)){
    alert("Please enter only numbers.")
  }
  else {
    alert(rndNum(specifiedNum))
  }
}
</SCRIPT>
</HEAD>
<BODY>

Type a number in the area below，then click Calculate.<BR>
The page will generate a random number between 1 and the
number you entered.<BR>

<FORM>
<TEXTAREA NAME="TextNum">10</TEXTAREA>
<BR>
<INPUT TYPE="button" VALUE="Calculate"
       onclick="tellUser(TextNum.value)">
</FORM>
</BODY>
</HTML>
程式9-3

圖9-3　檢查資料是否有錯誤11

tellUser函式首先使用isNaN方法來測試傳入的引數值 (如果引數值不是一個數字，則這個方法傳回值為True﹔如果是一個數字，則傳回False)。如果傳入值不為數字，tellUser函式會提示使用者只能使用數字。若傳入值為數字，tellUser函式會呼叫rndNum函式運作方式與程式9-2相同。

條件式運算元

條件式運算元就是簡化過的if…else敘述。以下這一行是條件運算元的使用方法。

alert (x>4?"x is greater than 4":"x is not greater than 4")

這個條件式敘述由一個布林代數測試開始，後面接著一個問號。接著代表當測試值為True時所得到的結果值，然後用冒號分隔當測試值為false時的另一個結果值。在這個alert例子中，條件式敘述是放在括弧中的程式碼。這個敘述端視x>4是否true或false，而傳回 "x is greater than 4" 或 "x is not greater than 4"。我們也可以利用if…else敘述重寫如下：

if (x>4) {alert("x is greater than 4")}
else {alert("x is not greater than 4")}

Switch敘述12

Switch敘述就像是if…else敘述的加強版。您可依照不同的情況，來設定不同的動作 (在其他些語言中，switch又稱為case敘述)。程式9-4使用一個switch敘述；圖9-4是執行的結果。

<HTML>
<HEAD>
<TITLE>Listing 9-4</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function testColor(givenColor){
  givenColor=givenColor.toLowerCase()
  switch (givenColor){
    case "blue" : alert("That is my favorite color!") ; break
    case "green": alert("Yuck，I don't like green.") ; break
    case "red"  : {
      alert("I don't like red as much as blue.")
      break
    }
    default:alert("I like blue the best.") ; break
  }
}
</SCRIPT>
</HEAD>
<BODY>
What is your favorite color?<BR>

<FORM>
  <TEXTAREA NAME="TextArea1">Blue</TEXTAREA><BR>
  <INPUT TYPE="button" VALUE="Test"
       onclick="testColor(TextArea1.value)">
</FORM>
</BODY>
</HTML>
程式9-4

圖9-4　使用一個switch敘述

switch敘述會依據不同的情況，執行一些不同的動作。switch敘述以switch為開頭，後面接著要被測試的敘述式，敘述式會用小括弧括起來。後面的大括弧中，則定義了在不同情況下的動作列表。動作格式為case後面接著switch敘述式的可能值，而冒號後才是想要執行的動作。當沒有任何值符合所設定的任何情況，您也可以設定預設 (default) 的動作選項。

在程式9-4中，當使用者在文字欄位輸入顏色名稱並按下Test鈕後，就會立刻呼叫testColor函式。這個函式將在多欄文字區的文字換成小寫，以便與敘述式的設定值做比較 (若沒有轉換，要測試使用者輸入內容會比較困難。舉例來說blue和Blue就不是兩個相同的字串)。接著開始switch敘述，它測試giveColor變數，若變數值等於blue、red或green則執行敘述中的動作。若沒有符合的case敘述，就會執行預設的動作。每一個case中，可以包含多個動作，每個動作放在不同行中，或以分號隔起來。每個case的最後一個動作都是break敘述，它代表這個case的結束，以防不小心執行到其他的case動作。Switch敘述是最近才被支援的，它在Netscape Navigator與Internet Explorer 3.0版本中並不支援 (技術上來說，並不是Internet Explorer 3.0不支援switch ，而是在Internet Explorer 3.0中所使用的JScript引擎的問題，新的Jscript引擎版本可以從13 msdn.Microsoft.com/scripting 下載，且可以使用在3.0版本與之後的版本)。

迴圈

使用迴圈能讓您可以將一個動作反覆地執行。迴圈對於減少您需要寫的程式碼很有幫助。在下一段中，在程式9-5使用4種迴圈之前，我們先對這幾種不同的迴圈先做一個快速的介紹。

for迴圈

for迴圈是最常見的迴圈類型之一，常用來執行指定次數的動作。下面此行程式是一個基本的迴圈，它會連續顯示10個警告視窗。

for (var i=1;i<=10;i++) {alert("This is a alert number"+i) }14

for迴圈由for這個字開始。後面接著用括弧括住的一段程式碼，裡面包含初值設定 (initialization)。裡面有一個計數變數(Counting Variable)，及一個變數的初值。初值設定後面接了一個分號，和一個測試運算式，這個運算式是一個布林代數敘述式。若測試運算式為true，就會執行在大括弧中所指定的動作；如果測試結果為False，就不會執行動作。因此，在這裡的例子中，只要i小於等於10就會一直執行迴圈中的動作。用括弧括住的這一段程式碼的第三部分包含了分號及累加運算元 (increment)，它是用來改變計數值。我們使用i++ 讓i加1，最後用大括弧包住要被指定動作的程式碼。

for...in迴圈

您可以使用一個for...in迴圈來檢視物件的所有屬性，或指向陣列中的每個索引值。舉例來說，下面此行程式將一個名為myArray的陣列中的每個索引值換行印出：

for (i in myArray) {document.write(myArray[i]+"<BR>")}

在書附光碟中，您將會在Tools資料夾中找到一個名為ObjInfo.htm的網頁。這個網頁能讓使用者指定想要檢視的物件，且使用一個for....in迴圈來逐一讀取物件資料並顯示所有物件的屬性。圖9-5的ObjInfo.htm顯示了有關document物件的資訊。

圖9-5　有關document物件的資訊15

while迴圈

一個基本While迴圈，就是只要布林測試值傳回True就決定執行動作。就像for迴圈一樣，While迴圈可以用來計數，也可以用它來測試資料值。這種型態的迴圈是由While和布林測試運算式，以及指定動作的程式碼所組成。下面的程式展示一個基本的while迴圈會連續顯示10個警示交談窗 (假定變數i初值為1)：

while (i<=10) {alert("This is alert number"+i):i++}

do...while迴圈

Do...While迴圈是while迴圈的變形，執行動作一次後，若條件依舊符合就會一直重複動作。它與其他迴圈主要不同的地方在於：因為是在迴圈結束時才測試，所以它至少會執行一次動作。下面這個程式即使5不小於或等於3，仍會產生一個警告對話方塊。

i=5;
do {alert("This is alert number"+i);i++} while(i<=3)

若將i設定成為1，就會出現3個警示窗。16

程式列表9-5使用了許多不同的迴圈。在這個例子中，使用者會被要求鍵入5個數字，這些數字將會被顯示螢幕上。我們就來看一下這個例子：一開始我們宣告一個新的陣列，並使用for迴圈來填入三個資料項目 (因為陣列的索引是由零開始算，所以索引使用0到2，而不是使用1到3 )。接著，我們使用一個for...in迴圈來讓使用者猜猜每個在陣列中的數字。

while迴圈決定使用者的猜測是否正確；若不正確，程式會要求使用者再試一次。這會一直繼續，直到使用者猜測正確或按下Cancel鈕。接著，我們使用一個if....敘述來測試是否使用者要結束而按下Cancel鈕。若使用者按Cancel鈕，就再經由一個if...else敘述來顯示一個交談窗，它會詢問使用者是要結束或繼續下一個數字。若使用者選擇結束，就使用break敘述。break敘述用於跳離各種類的迴圈。若使用者選擇繼續移動到下一個數字，就會進行continues敘述。然後繼續我們for.. in的動作，然後繼續下一個數字。最後當程式結束之後，使用者在瀏覽器視窗中會看到一個結束的訊息。

<HTML>
<HEAD>
<TITLE>Listing 9-5</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var numArray=new Array

for (var i=0;i<=2;i++){
  numArray[i]=Math.ceil(Math.random()*4)
}

alert("You will be asked to guess three numbers I have picked.")
for (j in numArray){
  guess=prompt("Guess between 1 and 4. Cancel will exit.","")
  while((guess!=numArray[j])&&(guess!=null)){
    guess=prompt("Nope! Try again or type 0 to quit.","")
  }

  if (guess==null){
    if(confirm("OK to quit，Cancel to guess the next number.")){
      break
    }
    else{continue}
  }

  alert("That's right!")
}

alert("Goodbye!")
</SCRIPT>
</HEAD>
</HTML>
程式9-5

當使用任何型態的迴圈，都應該要小心不要造成一個無限迴圈。一個無限迴圈是永遠不會跳離的。在很多情形下，都會發生無窮迴圈的情形。而且while迴圈比for迴圈更容易發生無窮迴圈的情形。舉例來說，下列的程式就會造成無限迴圈：

i=0
while (i<=10) {alert("This is alert number "+i);a++}

這計數的變數i永遠不會增加，而變數a反而會一直增加。因此i永遠小於10，所以迴圈永遠不會結束。17

Note

注意：不要在瀏覽器中執行這行程式碼。執行了之後，您的瀏覽器可能就會當在哪裡了。若發生了這種情況 (及您用的系統為Windows 95/98或Windows NT)，同時按下Ctrl、Alt、和Del鍵。它會啟動一個對話方塊，讓您選取已經停止回應的瀏覽器，然後選擇結束工作，以手動方式停止該程式。

Internet Explorer 5支援條件符合敘述 (Conditional Compilation Conditional Comments) 功能。因為這對於撰寫跨瀏覽器的程式上會有幫助，我們將在 第23章 中講述。

前幾章講的都是基本的Scripting技巧。在下一個章中，我們將會學習如何偵測程式錯誤與進行除錯工作。

實戰Dynamic HTML網站技術 視窗縮放
函式、條件式與迴圈


實戰Dynamic HTML網站技術=>除錯與錯誤處理

除錯與錯誤處理
小
工
具 加入書架
加入書籤
上一章
下一章

在前幾個章節中，我們已經將焦點放在使用基本的Scripting技巧，例如條件敘述、函式、和資料型態處理。如果您曾經試著將這些程式放入您自己的網頁上，您應該會注意到有些時候還是會發生錯誤的。在本章中，我們將討論常見程式的除錯練習和技巧，以及撰寫自動偵測錯誤的Scripting程式。

錯誤的種類

您會在網頁中遇到許多不同的錯誤，最常見的錯誤可以歸納下列幾類：

  • 語法錯誤1 就是沒有遵守語言規則而產生的錯誤。例如一個JScript函式後面沒有加括弧或字串外括了一個雙引號和一個單引號。語法錯誤通常十分容易偵測，因為他們通常都會顯示一個錯誤訊息。
  • 無法預期的錯誤情況 這是當遇到就算程式撰寫的很好都無法處理的情況。例如當一個函式只能傳遞一個數值的參數，不過傳入值卻是字串值時﹔或一段需要載入物件或框架的程式，而所需物件尚未完全載入完畢。要完全追蹤這些錯誤是十分困難的。
  • 邏輯錯誤 程式雖沒有語法上的錯誤，不過在執行時卻發生無法預期的錯誤。例如在計算稅率時用錯了計算的方程式，或在數學式中使用錯誤的運算元 (將 - 用成 + 或將 = = 用成 =)。這些可能是最難除錯的程式錯誤，因為他們並不會產生錯誤訊息。

接著我們將學習一些常見的除錯技巧。

除錯(Debugging)2

因為沒有一個程式設計師是完美的，所有測試和除錯的程式設計都是程式開發的一部份。程式除錯技巧有成千上萬種。本段將會涵蓋一些我們感興趣的技巧，範圍從一般錯誤預防練習，及使用特定除錯工具 (例如Microsoft Visual Interdev) 等。

錯誤預防和追蹤偵錯

有一個古老的格言說：「好的防禦就是最好的攻擊」。在程式設計的世界中，最好的無錯誤程式就是防止在一開始就發生錯誤。以下列出了一些有用的技巧，這些技巧可幫助你避免錯誤；或者讓你在發生錯誤後，能馬上找到錯誤發生的位置。

  • 取適當的變數。若您使用像S11和S12的變數名稱，而非strFirstName和strLastNamz e，則很容易發生錯誤。
  • 將原始碼格式化可讓您的程式容易閱讀。將程式碼內縮能幫您了解哪一行程式是一個迴圈的一部份，或哪個 <TD> 標籤是屬於表格的哪一列。
  • 建立小巧且可重複使用的函數。小函數可讓問題更容易顯示出來，您的函數若能重複使用多次，則您就不需要測試這麼多新的程式。
  • 將程式註解詳細地敘述。註解能有助於解釋每部分的程式碼，程式設計師為何會如此撰寫。3
  • 盡可能將script放在網頁的開頭。這可以確保程式可在使用網頁物件前就已載入了。因此，例如說函數和事件處理程式都在欲呼叫這些函數或程式的物件之前載入，如此就不容易發生錯誤了。
  • 在寫程式時, 先處理一些沒有辦法預測的情況。例如, 若某框架的程式要呼叫另一個框架的物件，在要存取該物件時，應該先測試目標的框架是否已經下載了，如此的測試會增加程式的穩定度。
  • 加入一段錯誤處理的程式來避免使用者使用時產生錯誤。這種技巧在本章稍後會提到。
  • 使用一些工具幫您撰寫無錯誤程式。就像Microsoft Visual Interdev和Allaire Homesite會讓您的程式碼用顏色來區別，它讓不同的標籤有不同的顏色，且所有用引號括住的文字都會有顏色。這可幫您找到一般錯誤，例如忘記加上標籤的三角括弧或在script中少了一個引號或大括弧。這些工具也自行處理縮排且對於常用函數也可產生程式碼。Visual Interdev和Microsoft Script Debugger包含除錯功能幫您追蹤問題。這些工具稍後也會更詳細說明。
  • 確定您可以獲得比瀏覽器提供的還多的錯誤資訊。 Microsoft Internet Explorer 5支援開發者模式，一個在螢幕上可顯示錯誤訊息的選項 (在下面的Note框中有說明)。前版的Internet Explorer自行在螢幕上顯示一些錯誤資訊。Netscape提供Communicator Console來處理除錯訊息。您在Netscape中的位址列中鍵入javascript：即會顯示Communicator Console。
  • 將某行程式加上註解符號來幫忙找出錯誤的程式碼。若您覺得某一行script會發生錯誤，您可在此行程式碼前加上兩條斜線(//) 將此行當作註解，若測試的是HTML可加上HTML的註解符號 (<!-- 和 -->)。
  • 當執行script時，可使用一些監測變數值與各種物件狀態的技巧。這些稍後將會討論。4
Note

在不同瀏覽器中會顯示不同的錯誤訊息。Internet Explorer 5會在視窗底部的狀態列中顯示一個訊息，警告使用者發生錯誤。若使用者在狀態列雙按，則會出現完整的錯誤視窗。 在一些瀏覽器中，錯誤訊息會立即出現在螢幕上的對話窗。Internet Explorer 5也可在任何錯誤對話窗中，選擇 "當網頁包含錯誤永遠顯示訊息" 選項設定這項效果，或在工具列功能表中Internet選項的進階頁次中選取 "在每個Script錯誤時顯示提示"命令。這種設定被視為顯示錯誤訊息的 "開發者模式"，強力推薦使用。

可觀察的變數和Run-Time程式設計

當設計程式時，能知道某個變數值或一個物件的狀態通常都蠻有用的。在網頁下載之後，建立及執行程式也有助於觀察變數值。程式列表10-1展示完成這些工作的幾種方式。圖10-1顯示這些結果。

<HTML>
<HEAD>
<TITLE>Listing 10-1</TITLE>
<SCRIPT LANGUAGE="JavaScript">
  function doIt(){
    a=10
    window.status=("a="+a)
    b=20
    alert("b="+b)
    c=a+b
  }
</SCRIPT>
</HEAD>
<BODY onload="doIt()">
<FORM NAME="frmDbg" onsubmit="eval(this.sDbg.value);return false">
  <INPUT TYPE="text" NAME="sDbg" SIZE="50">
  <INPUT TYPE="button" onclick="eval(frmDbg.sDbg.value)" VALUE="Run Code">
</FORM>
</BODY>
</HTML>
程式10-1

有很多方法來決定您在程式中不同元件的狀態。一個方式就是在警示對話方塊中或在瀏覽器視窗底部的狀態列上顯示有關元件的資訊。要改變狀態列的內容，只要將Window.status設定個值。如果您使用Internet Explorer版本4或更新版本當作您的測試平台，您也可以建立一個已命名的 <SPAN> 標籤，然後改變span的innerHTML性質，來在文件主體中顯示錯誤訊息。

5
圖10-1　許多除錯的方法

一般來說，區別偵錯程式和周圍一般程式碼是十分重要的，因為如此您才不會忘記在完成您的程式之前將它刪除。一個簡單可將偵錯程式碼變得比其他程式碼更清楚的方法就是不要將它內縮。一個更複雜的方式，則是替您的網頁設定一個 "除錯模式"。舉例來說，一個名為debug的變數可被設定成true或false。條件式迴圈在所有偵錯程式碼之外，設定來測試debug變數，且如果debug被設定成true則執行除錯程式碼。

在程式10-1中第2個技巧就是使用文字欄。當您按下 [Enter] 鍵或按下執行程式鈕，任何鍵入文字欄的程式碼將會被處理。使用這個技巧一旦網頁被載入後當您不知道您會想要哪些種類的資訊。任何合法的Jscript敘述都可以鍵入此欄來計算設定值，例如，若您填入alert(window.location)，就會顯示一個包含目前文件路徑位置的警示窗。若您填入alert(window.navigator.useragent)，則會顯示正在使用的瀏覽器資訊。

Script偵錯工具

例如像Script debugger，Visual Interdev，和Netscape JavaScript Debugger就特別設計用來除錯與分析scripting程式碼。Script Debugger是一個免費程式且在 msdn.microsoft.com/scripting 中可找到豐富的相關參考文件。Script debugger提供利用JScript，VBScript，和Java應用程式所建立網頁有關的除錯資訊。它能讓您：6

  • 一步步逐行執行script或設定中斷點來暫停執行。
  • 顯示和改變script的變數值和物件性質設定值。
  • 可幫IIS所架設的伺服器中執行的ASP程式除錯。

script debugger需要開發者的工作站安裝Internet Explorer 3.02或更新版本。一旦安裝Script debugger，它就可以從Internet Explorer的檢視功能表中執行或由Script中使用關鍵字 "debugger" 來自動地執行。Script debugger中一個主要的限制就是不能在同視窗中編輯和除錯。

Netscape JavaScript Debugger是一種和Script debugger相似的軟體。它可以從developer.netscape.com/software找到。

Visual Interdev是一種能快速建立Web應用程式且功能強大的開發環境。它是一個既可建立標準網頁和伺服器端資料庫應用程式的開發程式。Visual Interdev有內建除錯和網頁分析工具。它加入了所有script debugger的功能，並且包含了以下額外的功能：

  • 複雜的伺服/客戶端除錯工具來逐步執行程式且觀測變數的變化。7
  • 有一個視窗可顯示所選取HTML標籤的所有屬性。
  • 整合資料庫工具讓建立資料庫應用程式更容易。
  • 即見即所得的編輯功能。
  • 網頁與網頁上的script是利用樹狀控制的表示方式。
  • 簡單拉曳就能使用ActiveX Control。

錯誤處理(Error Handling)

由於程式語言例如VBScript和JavaScript漸漸變得更為複雜，程式設計師設計程式時所發生的錯誤也是越來越複雜。然而，您可以利用錯誤處理將程式寫入script中，它可以捕捉錯誤且解決它或警告使用者告知錯誤的訊息。舉例來說，若一個script呼叫一個尚未下載完畢的ActiveX控制項或Java applet，它一般都會產生一個錯誤對話窗顯示給使用者看。它可以用錯誤處理程式來聰明的捕捉錯誤。8

onerror事件處理器

處理onerror事件是一種捕捉及處理scripting程式錯誤的方法。當在一個特定物件中發生錯誤時，onerror事件會被觸發，且使用者會被告知。支援onerror的物件包括IMG、LINK、OBJECT、SCRIPT、STYLE，和最有用的window物件。Netscape Navigator 3.0版本和更新版本與Internet Explorer 4.0版本和更新版本支援onerror。程式列表10-2展示一個基本onerror事件的使用實例，且圖10-2及圖10-3顯示其結果。

<HTML>
<HEAD>
<TITLE>Listing 10-2</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function jHandleImageError(oImg){
  alert('Could not load the image '+oImg.name+". Loading alternate.")
  oImg.src='unavailable.gif'
}
</SCRIPT>
</HEAD>
<BODY>
This image does not use an error handler.
<IMG SRC="one.gif" NAME="ImageOne"><BR>
This image does use an error handler.
<IMG SRC="two.gif" NAME="ImageTwo" onerror="jHandleImageError(this)">
</BODY>
</HTML>
程式10-2

圖10-2　一個自行利用程式設計的錯誤訊息

當執行程式10-2時，一開始即試著下載圖形one.gif和two.gif，而這兩個圖檔是找不到的，因為兩個圖都沒放在隨書光碟中。ImageOne物件無法下載one.gif圖檔且觸發onerror事件。沒有任何動作被執行，因為此圖並沒有做錯誤處理，所以只留下一個遺失圖檔的圖示給使用者看。當瀏覽器試著去下載two.gif，onerror事件又再次被觸發。這次行內onerror事件處理程式捕捉到此錯誤。此事件處理器呼叫一個函式，利用一個錯誤訊息警告使用者，然後載入另一個選用的圖檔。這個行內事件處理程式也可使用在OBJECT和SCRIPT元件，無法載入檔案時來指向另一個可選擇的資源。9

圖10-3　接著載入了另一個圖

在window物件中，onerror用來捕捉一般的錯誤。程式列表10-3展示當沒有錯誤處理的網頁script呼叫不存在的物件會發生什麼事。

<HTML>
<HEAD>
<TITLE>Listing 10-3</TITLE>
</HEAD>
<BODY>
Clicking this button calls a non existent object.
<FORM><INPUT TYPE="button" VALUE="Click Me" onclick="FakeO.use()">
</FORM>
</BODY>
</HTML>
程式10-3

圖10-4　當程式10-3 執行時，Internet Explorer會出現一個錯誤對話窗10

當使用者按鈕時，它的onclick事件處理程式會試著使用一個不存在物件的方法。這會引發一個標準未定義物件的錯誤訊息，顯示在使用者面前，如圖10-4所示。下面這段程式捕捉錯誤的發生。結果顯示在圖10-5。

<HTML>
<HEAD>
<TITLE>Listing 10-4</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function errorHandler(msg,url,line) {
  strPrompt=("Captured error \n"+msg+"\n on line "+line+" in "+url+".")
  strPrompt+=("\nCancel display of standard error message?")
  if (confirm(strPrompt)){return true}
  else {return false}
}
window.onerror=errorHandler;
</SCRIPT>
</HEAD>
<BODY>
Clicking this button calls a non existent object.
<FORM><INPUT TYPE="button" VALUE="Click Me" onclick="FakeO.use()">
</FORM>
</BODY>
</HTML>
程式10-4

圖10-5　程式10-4處理錯誤的情形

當程式10-4被載入時, 利用window.onerror=errorHandler敘述來將errorHandler函數設定給window物件。這個敘述意謂著任何時刻當window物件觸動onerror事件時，errorHandler函式會被呼叫。errorHandler函式使用三個包含錯誤資訊的參數。msg參數包含錯誤訊息的文字，url參數提供錯誤發生網頁的URL，line參數提供產生錯誤在script中的行號。這些參數只有在window物件的onerror事件處理器中有用，不能用於其他物件，例如：images，使用這些參數，函式會利用設定的格式來顯示錯誤訊息，且包含可以取消的選項。若errorHandler函式傳回值為True，window物件不會出現額外的錯誤訊息。若傳回False或沒有傳回值，一般錯誤訊息會顯示出來。傳回值為True敘述，或設定window.event.returnValue性質為True，errorHandler函式也可以防止任何錯誤訊息顯示。

除了行內onerror事件處理器展示在程式列表10-2及window.onerror處理器展示在程式列表10-4，您可以建立一個特定包含錯誤處理程式碼的一段script程式，如下所示:11

<SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="onerror(msg.url.line)">
[...script commands...]
</SCRIPT>

這種型態的script程式只能使用在Internet Explorer中，不能使用在現在版本的Netscape中。

try...catch和throw敘述

現在新JScript的script引擎支援錯誤處理的新技巧，這個引擎是安裝Internet Explorer 5後就會安裝，且可以使用在IIS且更早版本的Internet Explorer上，這個新技巧就是try...catch敘述。當在伺服器端執行script時，server端沒有window物件可使用時，它就十分的有用。因為不同的錯誤處理程式碼可以放置在不同的問題程式區域。程式列表10-5顯示一個try...catch敘述。圖10-6顯示這個結果。

<HTML>
<HEAD>
<TITLE>Listing 10-5</TITLE>
<SCRIPT LANGUAGE="JavaScript">
try {
  document.write("This statement works.")
  document.write(fakeO.use())
  document.write("This statement does not work.")
}
catch (e) {
  strError=("An error occurred. The error number was "+e.number+". ")
  strError+=("The error message was \""+e.description+"\"")
  alert(strError)
}
</SCRIPT>
</HEAD>
<BODY>
</BODY>
</HTML>
程式10-5

12
圖10-6　程式10-5利用try...catach來處理錯誤

當網頁被下載後，會執行一段script程式。就像你看到的，由這段try的程式碼開始，它包含了一連串瀏覽器執行的敘述。若任何敘述產生錯誤，錯誤會被捕捉及傳遞到隨後的catch這段程式，它會建立並顯示一個錯誤訊息。

在try這段程式碼的第一個敘述是document.write方法, 沒有錯誤發生並且成功的執行著。第二行呼叫一個不存在的物件和方法。這會產生錯誤，catch這段程式也會被呼叫，它會顯示錯誤訊息。

catch敘述會自動接收一個包含錯誤物件的參數。這個物件有兩個性質，number和description。每個型態的script錯誤都被設定成一個獨一無二錯誤號碼。number性質可以來測試，且端視何種錯誤會有不同的效果。description性質包含錯誤的文字敘述。

try...catch敘述對於伺服器端特別有用，因為沒有window物件來捕捉錯誤。它也可以用來設定初值。舉例來說，下面的敘述會設定b的值為a，除非設定時有任何的問題 (例如b不存在)，則在這種情形下會設定值為5來代替。

try  {a=b}
catch  {a=5}

throw敘述可以被用來傳遞一個特定錯誤訊息給catch敘述。它也可用來傳遞錯誤訊息到在try...catch敘述的巢狀結構中，更高階層的錯誤處理程式。程式列表10-6展示這些技巧。13

<HTML>
<HEAD>
<TITLE>Listing 10-6</TITLE>
<SCRIPT LANGUAGE="JavaScript">
processedSuccessfully=false
sProb=""
while (!processedSuccessfully){
  try {
    try {
      intInput=prompt(sProb+"Enter a number to divide into 100.",4)
      // send specific error to inner handler
      if (isNaN(intInput)){throw "NaN"}
      if (intInput==0){throw "div0"}
      x=(100/intInput)
      sOutput=("100 divided by "+intInput+" equals "+x)
      processedSuccessfully=true
    }
    catch(e) {
      sErr="Handled in inner handler. "
      if (e == "NaN"){
        sProb=(sErr+"You did not enter a valid number.\n")
      }
      // send other errors to outer handler
      else{throw e}
    }
  }
  catch(e) {
    sErr="Handled in outer handler. "
    if (e=="div0"){
      sProb=(sErr+"You entered 0, which cannot be a divisor.\n")
    }
  else{sOutput=(sErr+e.description);break}
  }
}
document.write(sOutput)
</SCRIPT>
</HEAD>
<BODY>
</BODY>
</HTML>
程式10-6

程式列表10-6一開始提示使用者輸入一個數字。這個程式使用一個while..loop迴圈來持續提醒使用者直到輸入的數字合乎程式要求，或直到呼叫到break敘述，讓使用者跳出while迴圈。當輸入有效的數字時，程式會將數字除以100且將結果加入到sOutput變數，然後會顯示在瀏覽器視窗中。

然而有許多使用者預測的輸入錯誤可能會導致癱瘓此程序的進行。例如使用者可能會輸入0，而100除以0是沒有意義的，或使用者填入的是文字而非數字。除此之外，一些預期不到的錯誤也可能發生。因此，我們利用try、catch、和throw敘述在我們程式中來做測試，擷取，然後報告有這些型態的錯誤。

內部的try敘述測試是否使用者輸入的數字不是一個數字，和是否輸入數字是0。若任一個情況發生，throw會被使用來傳送錯誤訊息給catch敘述，而catch會建立一個特定的錯誤訊息。若沒有任何其他的錯誤發生，即會自動地和往常一樣傳送到catch。

若使用者輸入一個非數字 (文字或符號) 字串，內部的catch敘述會偵測到這個錯誤，然後會將他加入到sProb變數，然後將修改後的sProb字串值加到下一次要求使用者輸入數字的交談視窗中顯示。若使用者輸入0，錯誤還是會丟給外部的catch敘述，它也會修改sProb變數。在使用break敘述跳出while迴圈後，其他的錯誤描述會存在sOutput變數。document.write方法會在視窗中描述這些錯誤。為了產生如此的問題，複製程式到您的硬碟然後將x=(100/intput) 此行的註解去除。這將會引發顯示一個 'x' 尚未定義的錯誤訊息。

更多有關number性質14

存在Internet Explorer裏的JScript Script引擎可以傳回如表10-1所示的錯誤訊息。這個表格沒有列出在Scripting引擎之外物件 (如Media Player和其他的ActiveX控制項) 傳回的錯誤，且他們可以處理一般的錯誤。

錯誤數字 | 錯誤描述
5 | 無效的程序呼叫或引數
6 | 溢位15
7 | 記憶體用完了
9 | 下標數字超出範圍
10 | 這個陣列被固定住或暫時鎖定
1116 | 除以0
13 | 鍵入錯誤
14 | 沒有字串空間
17 | 不能執行所要求的運算17
28 | 沒有堆疊空間
35 | 副程式或函式沒有定義
48 | 載入DLL發生錯誤
5118 | 內部錯誤
52 | 錯誤的檔案名稱或數字
53 | 找不到檔案
54 | 錯誤的檔案模式19
55 | 檔案已經開啟
57 | 裝置I/O錯誤
58 | 檔案已經存在
6120 | 磁碟已滿
62 | 輸入在檔案結尾之後
67 | 太多檔案
68 | 裝置未安裝21
70 | 不允許使用
71 | 磁碟未準備好
74 | 不能替不同磁碟更改名稱
7522 | 路徑/檔案存取錯誤
76 | 路徑找不到
91 | 物件變數或區塊變數未設定
92 | For迴圈未設初值23
93 | 無效的圖像字串
94 | 使用Null不正確
322 | 不能建立所需的暫存檔
42424 | 需要物件
429 | 自動化伺服端不能建立物件
430 | 類別不支援自動化
432 | 在自動化運算時找不到檔名或類別名25
438 | 物件不支援 <項目> 性質或方法
440 | 自動化過程錯誤
445 | 物件不支援此動作
44626 | 物件不支援這個名稱的引數
447 | 物件不支援目前的設定
448 | 找不到名稱引數
450 | 錯誤的引數的數目或無效的性質設定27
451 | 物件不是一個集合
453 | 找不到指定的DLL函式
458 | 使用自動化型態的變數在JScript中不支援
50128 | 無法設定變數
502 | 利用scripting來操作物件不安全
503 | 初值改變對物件不安全
504 | 建立物件不安全29
5000 | 不能設定 'this' 物件
5001 | <項目> 不是一個數字；需要一個數字
5002 | <項目> 不是一個函式；需要一個函式
500330 | 不能設定到一個函式的結果
5004 | <項目> 不是可索引的物件；不能索引物件
5005 | <項目> 不是一個字串；需要一個字串
5006 | <項目> 不是一個資料物件；需要一個資料物件31
5007 | <項目> 不是一個物件；需要一個物件
5008 | 不能設定此項目；不合法的設定
5009 | <項目> 未定義；未定義的關鍵字
501032 | <項目> 不是一個布林代數；需要布林代數
5011 | 不能執行一個分離的script程式
5012 | 不能刪除此項目；需要物件成員
5013 | <項目> 不是一個VBArray；需要一個VBArray33
5014 | <項目> 不是一個JScript物件；需要一個JScript物件
5015 | <項目> 不是一個enumerator物件；需要一個enumerator物件
5016 | <項目> 不是一個規則敘述物件；需要一個規格敘述物件
501734 | 規則敘述中語法錯誤
5018 | 無法預期的定量詞
5019 | 在規則敘述中需要 ']'
5020 | 在規則敘述中需要 '['35
5021 | 在字元集中無效的範圍

您將會注意到在這個表格中所出現的數字本質上與真正用number性質所得到的數字不同。程式列表10-7展示如何將number所得到的數字與前面表格中的數字來做轉換。圖10-7顯示結果。

<HTML>
<HEAD>
<TITLE>Listing 10-7</TITLE>
<SCRIPT LANGUAGE="JavaScript">
try {
  x=y
}
catch (e) {
  strError=("An error occurred. error.number was "+e.number+"\n")
  strError+=("Convert this and get "+(e.number&0xFFFF)+"\n")
  strError+=("The error message was \""+e.description+"\"")
  alert(strError)
}
</SCRIPT>
</HEAD>
</HTML>
程式10-7

圖10-7　程式10-7將錯誤轉換成表10-1中所列的值36

下面是一個技術性的說明。在表10-1的數字只表示在e.number中較低位數的數字。第二行參考e.number執行一個AND運算的位元比較，利用 & 運算元來取得只有較低的位元。這也被視為是實行了一個位元遮罩(bit mask)。您可以從 msdn.microsoft.com/scripting 網站得到有關 & 運算元更多的資訊，此網站也可以找到更多有關錯誤處理的資訊。

到目前為止，我們看了一些HTML和Scripting的函式和特性。第三部份將介紹串接式樣式表 (Cascading Style Sheets;CSS)，一個從 Internet Explorer 3以來就出現的技術，但從當時以來不曾被大力擴展開來。CSS提供您對於網頁的外觀有較多的控制，且更容易使整個網站有一致性的外觀和感覺。

實戰Dynamic HTML網站技術 視窗縮放
除錯與錯誤處理


實戰Dynamic HTML網站技術=>CCS 簡介

CCS 簡介
小
工
具 加入書架
加入書籤
上一章
下一章

在過去幾年，HTML的標籤種類與數目增加了許多。除了標準的標籤外，各家瀏覽器還各自發展出專門的標籤，以擴充瀏覽器的功能。但截至目前為止，卻沒有一種瀏覽器能支援所有的HTML標籤。在利用專門的標籤來設定文件的格式時，您必須將新標籤加入在文件內容，通常這樣會取代掉那些原本已經廣受支援的標籤。雖然，這麼做可以使網頁內容的外觀 (或樣式) 比較接近您原始的構想，但是卻也會導致其它問題。其中最顯著的就是：網頁也許在特定的瀏覽器中能很完美地呈現，但卻不保證在另一瀏覽器中也是如此。此外，一旦要改變整個網站的外觀和感覺時，必須一一修改網站上所有網頁文件的標籤設定。

為了避免上述的困擾，全球資訊網協會 (World Wide Wed Consortium;W3C) 提出了串接樣式表 (Cascading Style Sheets;CSS) 規格，以提供一個將樣式從文件中分離出來的簡單模式。只要是依據這個規格的樣式表，就可以加入網頁或網站中，以設定網頁或網站中所有標籤所呈現出來的外觀或樣式。舉例來說，我們可以建立一個這樣的樣式表，在這個樣式表中，我們將 <H1> 標籤重新定義如下：字體為粗體、字型大小為24 pt、字型為Verdana，此外還有一公分寬的白色邊框及紅色背景。透過這樣一個樣式表的定義，在很短的時間內即可改變網站上所有<H1> 標籤的設定。透過CSS的樣式與文件分離的特性，先前提到需要一一改變文件中所有標籤設定的問題，現在只要靠一些樣式技巧就可以解決了。此外，CSS還提供一個前所未有的網頁文件控制方式，這種方式可以控制網頁文件的外觀和版面配置。利用CSS，您可以改變各種樣式，舉凡字體大小、字型、文字顏色和字距與行列間的距離，及元件周圍的邊界距與留白，甚至文件中物件的絕對位置。

動態樣式 (Dynamic Styles) 是微軟公司用在Internet Explorer上的一項CSS實作方法。它的內容十分接近CSS 1 (Cascading Style Sheets Level 1)，且也比任何一個常見的瀏覽器更符合最新標準CSS 2的規格。雖然，嚴格來說，「動態樣式」指的是參考微軟公司的CSS實作技術，不過，在這本書中，筆者我們 (和其他網路組織一樣) 將同時使用 "Cascading Style Sheets"、"CSS"、"styles" 和 "Dynamic Styles" 等詞彙，因為它們所指的東西其實都差不多。

雖然目前已經有許多瀏覽器都支援樣式規格 (包括Internet Explorer 3.0和Netscape Navigator 4或之後的版本)，但比較起來，仍屬Internet Explorer 4.0和5.0版本對於CSS的支援度最高。不過，並沒有任何一種瀏覽器可以支援全部的CSS 2規格，部份原因是因為CSS 2是為了要延伸樣式所能應用的媒體，包括聲音。想要進一步瞭解W3C中各種CSS規格，可連上W3C網站1 www.w3.org/style/ ，這裡提供了非常詳細、易讀、且有用的資料。

隨著對於CSS的規格漸漸為各方所重視，Netscape已經保證將會讓Netscape 5.0版本對CSS有較高的支援度；此外，Opera Software的Opera瀏覽器3.5以後版本也會盡量支援CSS。

本章將會討論兩種設定樣式的方法：

  1. 使用STYLE屬性來設定個別元件的樣式。
  2. 使用樣式表 (Style Sheets) 來設定一個網頁或整個網站的樣式。

樣式表可以直接包含在文件本身，或者也可以是一個由外部連結到HTML文件的檔案。接下來這一段將解釋使用這些方式來設定樣式的基本語法。至於如何透過script語言來設定樣式，請參考2 第15章 。

行內樣式

行內樣式 (In-Line Style) 是一種可套用到網頁中某個特別標籤的樣式設定方式，您可以利用STYLE屬性來套用一個行內樣式，到網頁中的任一個標籤上。跟其他屬性一樣，STYLE屬性只會影響包含此設定的標籤上，就像設定圖形WIDTH屬性只會影響到其所設定的圖形一樣。因此，行內樣式最大的用處在於單獨對某一元件做精確的控制，不會讓整個網頁和網站有大規模的改變。

讓我們來看一個未設定樣式的簡單HTML文件，見程式列表11-1，您可以在圖11-1中看到此文件的瀏覽結果。

在這個文件中，使用了在設定樣式上特別好用的 <SPAN> 標籤，由於這組標籤是一種容器 (Container) 標籤，也就是說，任何置入這組標籤之間的內容將獨立於其他的網頁內容，成為一個獨立的元件。不過由於在程式列表11-1的網頁中，介於 <SPAN> 和 </SPAN> 之間的文字尚未設定任何樣式，因此這些文字在瀏覽器中看起來跟其他文字並沒什麼兩樣。

<HTML>
<HEAD>
<TITLE> Listing 11-1 </TITLE>
</HEAD>
<BODY>
<SPAN> This text is in a SPAN. </SPAN><BR>
This text is not in a SPAN.
</BODY>
</HTML>3
程式11-1

圖11-1　一份未設定樣式的簡單HTML文件

我們可在原始碼中加入一個行內樣式，以利用font-weight性質將SPAN元件中的文字變成粗體。先參考程式列表11-2，然後在圖11-2可看到改變後的結果。

<HTML>
<HEAD>
<TITLE> Listing 11-2 </TITLE>
</HEAD>
<BODY>
<SPAN STYLE="font-weight:bold">
This text is in a SPAN. </SPAN><BR>
This text is not in a SPAN.
</BODY>
</HTML>
程式11-2

4
圖11-2　一個套用行內樣式的例子

請注意，在程式列表11-2中的 <SPAN> 標籤中，現在包含一個STYLE屬性，因此任何包含在SPAN元件的文字，都將會受到這個屬性的影響。此外，也請注意一下STYLE屬性的語法，STYLE屬性的設定值必須放在引號之間 (" ")。而設定值包含的則是樣式宣告。在這裡，特定的性質名稱 (例如font-weight) 之後出現的是冒號與性質設定值 (樣式表的設定語法和行內樣式設定有一些不同，本章稍後會再介紹)。

在STYLE屬性中，您可以同時設定一個以上的樣式宣告。舉例來說，在程式列表11-3，除了原來的font-weight粗體性質外，可再加上font-style性質 (設定值為italic) 。注意兩個樣式宣告必須放在同一個引號之間，然後中間以分號( ; )相隔。圖11-3展示的是設定兩種樣式後的瀏覽結果。

<HTML>
<HEAD>
<TITLE> Listing 11-3 </TITLE>
</HEAD>
<BODY>
<SPAN STYLE="font-weight:bold;font-style:italic">
This text is in a SPAN. </SPAN><BR>
This text is not in a SPAN.
</BODY>
</HTML>
程式11-3

圖11-3　一個設定多個行內樣式在同一個標籤的例子5

如果您熟悉HTML，您應該會注意到程式11-2和11-3這兩個例子的效果，其實就算不使用動態樣式，利用傳統HTML的語法，一樣能做到同樣的效果。雖然HTML的確提供了一些基本的樣式設定，例如：粗體、斜體等，但是動態樣式卻還能提供了格式設定與版面配置的選擇，從字型、絕對定位到多媒體濾鏡等，都能有更好的控制方式。

到現在為止，我們使用樣式來設定個別元件的格式。CSS也可讓您一次控制整個網頁或網站的樣式，您在下一段內容中可以看到。

樣式表

一個樣式表是由一個或多個樣式宣告 (或稱為樣式規則) 所組成。一般而言，樣式表可以直接包含在網頁文件內，或是在文件之外的一個獨立檔案。一樣式宣告會由選擇器 (Selectors) 和跟隨的宣告區段 (declaration block) 所組成，如下面的例子所示:

SPAN {font-weight:blod ; font-style:italic}

選擇器只是個樣式要套用的項目。在大部分情況下，選擇器本身就是HTML標籤 (雖然它也可以是個通用的類別，詳細稍後本章會提到) ，不過，只利用標籤名稱來命名，而省略了一般HTML標籤前後的括號 (< >)。在上面的例子中，SPAN就是我們的選擇器，所以，所有在文件中的SPAN標籤將會遵照樣式所定義的規則來設定樣式。

緊跟在選擇器後面的是用大括號括起來的宣告區段，這是一連串以分號分隔的樣式宣告。在這個例子中包含了兩個樣式宣告：font-weight: bold和font-style : italic。6

截至目前為止，這些樣式宣告對於網頁還不會有任何作用。因為，我們還必須將這些樣式宣告變成網頁內容或是外部鏈結樣式表的一部份。

整頁樣式表

一個整頁 (或嵌入) 樣式表會被直接加入網頁文件中，也就是成為HTML原始碼的一部份。這種形式的樣式表必須包含在 <STYLE> 和 </STYLE> 標籤之間，且必須放在HTML文件的起始區塊間 (也就是 <HEAD> 和 </HEAD> 之間)。

在程式列表11-4中，我們將上一節的樣式定義加入整頁樣式表中。正如您在圖11-4看到的，輸出結果和我們之前使用行內樣式的結果是完全相同的 (前一頁的圖11-3) 。在這個例子中，雖然樣式被分開定義了，但它仍會套用到文件中所有的 <SPAN> 標籤上。

<HTML>
<HEAD>
<TITLE> Listing 11-4 </TITLE>
<STYLE>
  SPAN { font-weight : bold ; font-style : italic }
</STYLE>
</HEAD>
<BODY>
<SPAN> This text is in a SPAN. </SPAN> <BR>
This text is not in a SPAN.
</BODY>
</HTML>
程式11-4

7
圖11-4　一個整頁套用樣式的例子

在程式列表11-5中，我們繼續擴展這個HTML檔案的樣式設定，以展示整頁樣式表的「可重複使用性」。這個例子比前面的例子包含了更多文字。在這其中，有些文字是夾在 <SPAN> 標籤之間，有些則不是。因為我們已經將 <SPAN> 元件的樣式宣告設定成整頁樣式表，因此樣式所定義的格式都會套用到那些SPAN元件上，而不會套用SPAN元件以外的區域。在圖11-5您將可以明顯看到這些差異。

<HTML>
<HEAD>
<TITLE> Listing 11-5 </TITLE>
<STYLE>
  SPAN { font-weight : bold ; font-style : italic }
</STYLE>
</HEAD>
<BODY>
<SPAN> This text is in a SPAN. </SPAN> <BR>
This text is not in a SPAN.
<SPAN> This text is in a SPAN. </SPAN> <BR>
This text is not in a SPAN.
<SPAN> This text is in a SPAN. </SPAN> <BR>
This text is not in a SPAN.
</BODY>
</HTML>
程式11-5

圖11-5　使用整頁套用樣式影響所有的SPAN元件

現在讓我們加入更多定義到樣式表。在程式列表11-6中，我們將階層1的標題 (<H1>標籤) 樣式設定為：16點、粗體、及紅色；階層2的標題 (<H2>標籤) 則定義為24點、斜體、及綠色。圖11-6可看出樣式表如何讓SPAN、H1、和H2等元件原有的樣式設定失效。8

<HTML>
<HEAD>
<TITLE> Listing 11-6 </TITLE>
<STYLE>
  H1   { font-size: 16pt; font-weight: bold ; color :red }
  H2   { font-style: italic ; font-size: 24pt ; color :green }
  SPAN { font-weight : bold ; font-style : italic }
</STYLE>
</HEAD>
<BODY>
<SPAN> This text is in a SPAN. </SPAN> <BR>
<H1> This text is in a H1. </H1> <BR>
<H2> This text is in a H2. </H2> <BR>
</BODY>
</HTML>
程式11-6

圖11-6　使用整頁套用樣式改變不同的元件樣式

如果想改變程式11-6中任何一個元件的外觀，那麼，您只需改變樣式表就可以了。舉例來說，如果將H2樣式定義中的文字顏色改為藍色，那麼，文件中所有的H2元件都將會反映這個變化。

如果您想針對網頁中的某個特定元件，設定為不同的格式，但是又不想影響到其它相同的元件，那麼在這種情況下，樣式定義方式將會和設定整頁樣式表有所不同。您可以為該特定元件設定行內樣式，如此即可讓表頭區域中的樣式表設定失效。程式列表11-7和圖11-7提供了一個例子。在圖11-7，文件中第一個H2元件使用的是表頭區的樣式設定，但第二個H2元件因為有一個行內樣式，因此整頁樣式表中的font-size宣告就會失去作用。

<HTML>
<HEAD>
<TITLE> Listing 11-7 </TITLE>
<STYLE>
  H1   { font-size: 16pt; font-weight: bold ; color :red }
  H2   { font-style: italic ; font-size: 24pt ; color :green }
  SPAN { font-weight : bold ; font-style : italic }
</STYLE>
</HEAD>
<BODY>
<SPAN> This text is in a SPAN. </SPAN> <BR>
<H1> This text is in a H1. </H2> <BR>
<H2> This text is in a H2. </H2> <BR>
<H2 STYLE="font-size:36pt"> This is modified H2 text. </H2> <BR>
</BODY>
</HTML>9
程式11-7

圖11-7　一個行內樣式讓整頁套用樣式失效的例子

外部鏈結樣式表

前面幾節所提到的樣式都是直接定義在網頁文件，事實上，您也可以使用外部鏈結樣式表，來控制多個網頁或整個網站的樣式。「鏈結的 (或外部的) 樣式表」其實只是一個包含樣式宣告的文件檔，其副檔名為CSS，並且是獨立於HTML文件之外的另一個檔案。至於要使用外部鏈結樣式表的HTML文件則是以 <LINK> 標籤，建立檔案之間的參考與連結關係。

接下來，我們利用程式11-7的樣式定義來示範一下鏈結樣式表。首先，我們得先設定一個樣式表檔案，其實任何一個文字編輯器都可以完成這個工作，例如Windows 98的記事本就可以，接著就來建立一個包含如下樣式定義的檔案：

H1 { font-size: 16pt; font-weight: bold ; color :red }
  H2 { font-style: italic ; font-size: 24pt ; color :green }
  SPAN { font-weight : bold ; font-style : italic }10

接著，我們將這個檔案以檔名style.css來儲存 (當您在書附光碟中尋找這個檔案時，請注意副檔名) 。注意，在編輯外部鏈結樣式表的內容時，樣式的前後不需加上 <STYLE> 和 </STYLE> 標籤。

現在，我們可以建立一個包含外部鏈結樣式表的HTML文件。這份文件的原始碼如程式列表11-8所示；其瀏覽結果則請參考圖11-8。

<HTML>
<HEAD>
<TITLE> Listing 11-8 </TITLE>
<LINK HREF="style.css" REL="STYLESHEET" TYPE="text/css">
</HEAD>
<BODY>
<SPAN> This text is in a SPAN. </SPAN> <BR>
<H1> This text is in a H1. </H2> <BR>
<H2> This text is in a H2. </H2> <BR>
<H2 STYLE="font-size:36pt"> This is modified H2 text. </H2> <BR>
</BODY>
</HTML>
程式11-8

圖11-8　一個外部鏈結樣式的例子

<LINK> 標籤只能用在HTML的標頭區塊 (也就是 <HEAD> 和 </HEAD> 之間)中。<IMG> 標籤一樣，<LINK> 標籤也用HREF屬性來設定目標檔案的來源位置；而REL屬性則指出這個鏈結所參考的是一個樣式表；至於TYPE屬性則是指定樣式的型態，目前普遍支援的樣式型態為 "text/css"。11

鏈結樣式表對於HTML文件的樣式設定效果，其實和使用整頁套用 (嵌入) 樣式表相同。在HTML文件中，只要在style.css檔案中定義過的元件標籤，都會使用所指定的樣式來顯示。

因為外部樣式表並非包含在任何特定的HTML檔案中，因此您可以將一個鏈結 (外部) 樣式表鏈結到多個HTML文件。舉例來說，您可以建立一個可套用到整個網站的樣式表，然後讓網站上的每一個網頁都鏈結到這個樣式表檔案。這種功能好處是：若要讓網站內的所有網頁都能維持一致的外觀或感覺時，只要修改套用在整個網站的CSS檔案內容，就能影響到整個網站，因此網站維護就變得相當輕鬆。相對地，您也可以在一份文件中使用多個 <LINK> 標籤，來鏈結多個不同的樣式表 ( 這個特性在Internet Explorer 3.0中並不支援 )。此外，若使用 @import命令可在樣式表再加入其他樣式表。整頁套用樣式和鏈結外部樣式都能使用這個命令。舉例來說，我們可以修改一下style.css檔案，來加入另一個樣式表。如下所示:

@import:url(ie.css);
H1 { font-size: 16pt; font-weight: bold ; color :red }
H2 { font-style: italic ; font-size: 24pt ; color :green }
SPAN { font-weight : bold ; font-style : italic }

這會使第二個檔名為ie.css的樣式表 (放置在和style.css相同的目錄中) 被載入到style.css樣式表檔案中。如這裡所示，任何@import規則都必須置於樣式表檔案開頭，也就是在所有樣式定義的前面。而在 @import設定列中，冒號 (:) 和分號 (;) 也都是必須的。此外，目前Netscape並不支援 @import規則。

集體設定與屬性速記

上幾段中的樣式定義例子都是撰寫成完整的格式。為了降低設計者的工作量與縮減樣式表大小，CSS1支援一個叫做「集體」 (Grouping) 的宣告方式，它可以使一組用逗點相隔的選擇器都套用相同的樣式。舉例來說，您可能會撰寫如下的樣式定義:

H1 { font-size: 16pt; font-weight: bold ; color :red }
H2 { font-size: 16pt; font-weight: bold ; color :red }
H3 { font-size: 16pt; font-weight: bold ; color :red }12

但是若使用集體宣告，原始碼就可以縮減如下所示:

H1，H2，H3 { font-size: 16pt; font-weight: bold ; color :red }

您也可以使用速記法 (Shorthand) 屬性 (也被稱做複合屬性)，將一些樣式屬性聚集起來。使用速記法性質能讓您同時設定多個相似的性質。假設有一個樣式定義包含了font-weight、font-size，和font-family等三個和字型有關的性質：

H1 { font-weight:blod ; font-size : 16pt ; font-family: Verdana }

則下面的速記法屬性設定也可得到同樣的樣式設定：

H1 { font : bold 16pt Verdana }

使用速記屬性時，個別的屬性必須依特定的順序排列。換句話說，下面這個有一點不同的原始碼：13

H1 { font : 16pt bold Verdana }

將不會產生您所期望的結果，因為font-size和font-weight性質的位置相反了。

還有很多其他的速記法性質，例如: border、margin和padding。您可以在 第12 、 13章 中看到更多CSS速記屬性的資訊，以及這些屬性的特定排列順序。此外，您也可以在SBN Workshop網站或本書所附的光碟中找到這些資訊。在光碟中，看一下Workshop(References) 的DHTML、HTML & CSS、 CSS、CSS Attributes Reference網頁。若想要看看網站上的版本，請連至MSDN online Resource網頁14 msdn.microsoft.com/resource/schumandhtml.htm ，或開啟隨書光碟中檔名為MSDN_OL.htm的檔案，然後選擇CSS Attributes。

繼承特性

幾乎在每一個網頁中，您都可以發現到很多HTML元件都會包含另一個HTML元件。正如您在前幾章學到的，這些嵌入元件通常都被稱為巢狀元件 (Nested Elements) 或子元件 (Child Objects)。在程式11-9這個例子中，一個B元件被包含在SPAN元件之內，在圖11-9可看到出在SPAN元件內出現的粗體文字效果。

<HTML>
<HEAD>
<TITLE> Listing 11-9 </TITLE>
</HEAD>
<BODY>
<SPAN> This is some <B>bolded</B> text in a SPAN. </SPAN>
</BODY>
</HTML>
程式11-9

15
圖11-9　一個巢狀元件的例子

動態樣式支援一個稱做「繼承」的特性，繼承的意思就是內部子元件 ( 在程式列表11-9中的B元件) 的樣式將由外部元件或父元件 ( 如程式列表11-9中的SPAN元件 ) 的樣式所決定。除了繼承外部元件的樣式，內部子元件也會套用針對其本身所設定的其它或不同的樣式。舉個實例，在程式列表11-10中，我們在程式碼中加入一個樣式表來宣告SPAN與B元件的樣式。我們可以在圖11-10中看到此網頁的瀏覽結果：

<HTML>
<HEAD>
<TITLE> Listing 11-10 </TITLE>
<STYLE>
  SPAN { font-size:16pt ; font-style : italic ; color: red }
  B { font-size : 24pt }
</STYLE>
</HEAD>
<BODY>
<SPAN> This is some <B>bolded</B> text in a SPAN. </SPAN>
</BODY>
</HTML>
程式11-10

圖11-10一個巢狀元件的例子

在圖11-10中，所有包含在SPAN元件的文件樣式為16 pt、斜體、紅色。由於B元件被包在SPAN元件之內，因此會繼承這些樣式。然而，它也混合加入本身由整頁樣式表所宣告的粗體樣式及24pt字型大小，因此最後，B元件內部的文字樣式將變成24pt、斜體、紅色和粗體。16

繼承性質可以讓您建立文件的預設樣式，好讓文件中的所有元件都能套用這個樣式。想要設定預設樣式，您只針對BODY標籤來設定一個樣式表就好，因為BODY是網頁中所有元件的父元件，所以，文件中的所有元件都會繼承設定在BODY元件中的樣式定義。

Note

在繼承系統中，有一個很重要的例外，那就是在某些瀏覽器中，表格不會繼承由BODY元件而來的許多屬性。為了解決這個例外的狀況，建議您可以另外加入表格TABLE和TD元件的樣式宣告。

類別 (Class)

CSS支援類別 (Class) 的建立。簡單來說，類別就是網頁中現有元件的變化。舉例來說，假定您想要在整個文件中都使用 <B> 標籤，但您希望在不同的地方，相同的標籤能還有不同的小變化。正如程式列表11-11所示，您可以建立您想要樣式的B元件類別。一般而言，B元件只會顯示粗體黑色的樣式，而類別的作用可在此替標籤加上額外定義的樣式。因此，在例子中，每個B元件依然是粗體，只是類別另外定義了特定B元件的字體大小。請參考圖11-11的瀏覽結果。

<HTML>
<HEAD>
<TITLE> Listing 11-11 </TITLE>
<STYLE>
  B.large { font-size:24pt }
  B.small { font-size : 8pt }
</STYLE>
</HEAD>
<BODY>
<B> This is a standard B.</B>
<B CLASS="small">This uses the small class. </B>
<B CLASS="large"> This uses the large class.</B>
</BODY>
</HTML>
程式11-11

17
圖11-11　類別B只改變字型大小

類別的定義方式是在選擇器名稱後面加上一點，然後再緊接類別名稱 (例如：(B.large)。接著，再利用大括號引入樣式設定的敘述，來設定類別的設定值。目前，並沒有瀏覽器可以支援在單個標籤中定義兩個以上類別層級，例如：你不能這樣使用B.large.bold類別。至於要將類別所設定的樣式套用在元件上時，您必須在標籤中利用CLASS屬性來指定，就像程式列表11-11中示範的 <B> 標籤一樣。

如果不想針對特定標籤設定類別，那麼，您可以設定整頁類別 (Global class)，如此這個類別就可以套用於所有元件上。整頁類別是一個功能強大的特性，因為網頁上的所有標籤都可以使用這種類別，就像程式列表11-2所示。圖11-12可以看到瀏覽結果。

<HTML>
<HEAD>
<TITLE> Listing 11-12 </TITLE>
<STYLE>
  .large { font-size:24pt }
  .small { font-size : 8pt }
</STYLE>
</HEAD>
<BODY>
Standard Text.
<H2 CLASS="small"> The small class on an H2 element. </H2?
<SPAN CLASS="large">The large class on a SPAN element.</SPAN><BR>
<P CLASS="small">This small class on a P element. </P>
<B CLASS="large">This large class on a P element. </B></P>
</BODY>
</HTML>
程式11-12

圖11-12　所有的元件都受整頁類別的影響18

鏈結 (Links)

使用動態樣式，您也可以改變鏈結標籤 (也就是 <A> 標籤) 在不同狀態時的樣式。 <A> 標籤和其它的標籤有點不同，因為它有四種不同的狀態，這些狀態稱作虛擬類別(pseudoclasses) ，分述如下：

虛擬類別 | 狀態 | 預設外觀
link | 此連結尚未被連結過19 | 藍色底線
visited | 已連結過的連結 | 紫色底線
hover | 滑鼠指標在連結上停留 | 藍色底線20
active | 滑鼠在連結上按鈕 | 藍色底線

在Internet Explorer中， <A> 標籤可以提供上述4種虛擬類別。但是在目前的Netscape中，則只有link和visited兩種而已。

當您建立一個樣式表時，您可以在鏈結標籤名稱之後加上冒號，然後加上虛擬類別的名稱，來修改鏈結樣式。如下所示：

A:link { color: yellow }
A:visited { color: red }
A:hover { color:green }
A:active { color:blue }

程式列表11-13展示了如何使用這些虛擬類別，在Internet Explorer中建立一個簡單的文字效果。21

<HTML>
<HEAD>
<TITLE> Listing 11-13</TITLE>
<STYLE>
   A:link { text-decoration: none }
   A:hover { color:red ; text-decoration:underline }
</STYLE>
</HEAD>
<BODY>
<A HREF="http://msdn.microsoft.com">msdn.microsoft.com</A><BR>
<A HREF="http://microsoft.com">microsoft.com</A><BR>
<A HREF="http://www.w3.org/Style">www.w3.org/Style</A><BR>
<A HREF="http://www.w3.org">www.w3.org</A><BR>
</BODY>
</HTML>
程式11-13

圖11-13　當滑鼠移到到鏈結上方時，文字會亮起來並出現底線

第一個樣式 (A:link) 用來設定一般鏈結在網頁上的顯示方式。其中，將text-decoration設定成none，是為了消除鏈結文字的預設底線。而當使用者移動滑鼠到一個鏈結上時，文字將進入到hover狀態，此時A:hover所設定的樣式就會開始作用，所以鏈結文字會被加上底線，並變成紅色。

Note

一般來說，並不推薦刪除一般行內超鏈結的底線。因為根據使用率研究顯示，使用者通常習慣將一段加上底線的文字當作是一個超連結。要是超鏈結沒有使用底線，那麼，使用者將不會認為那是一個真的連結。但是在上面的例子中，去除超鏈結底線的效果，倒還不錯，因為我們是把它用在導覽選單上。此外，我們也不建議您將滑鼠指標經過的連結變成粗體，因為這樣會使得文字的寬度被改變，而導致文字過長超過網頁寬度。

串接樣式22

經過這些串接式樣式表的討論，您或許會懷疑cascading這個字的意義為何。其實它的意義就是CSS可以讓多個樣式表影響同一個文件。大部份的情況下，網頁設計者都會設定這些樣式表。一些瀏覽器 (包括Internet Explorer) 允許使用者建立自己的樣式表，以改變網頁的版面配置，例如，增加文字大小及文字顏色。而當多個樣式表相互套用時，就稱為相互串接 (Cascade)。

很明顯的，當多個樣式表同時套用到一個文件時，將會產生一些衝突的現象。在一些瀏覽器中，網頁設計者的樣式將會優先於使用者設定的樣式，但其它瀏覽器則剛好相反。而網頁設計者和使用者所設定的樣式皆優先於預設的樣式。當多個設計者設定的樣式衝突時，通常最後設定的樣式之優先權最高。

如果您想要對於一個特定的樣式，給予較高的重要性，您可以加入一個important性質到樣式定義宣告中，如下所示:

H2 { color:red !important; font-style : italic }

需注意的是驚嘆號要放在樣式定義與important之間，任何沒有加入important的宣告會被視為一般的宣告。不論樣式是誰設定的，important宣告的樣式定義永遠比一般樣式擁有更高的優先權。不過，Netscape Navigator目前並不支援important宣告。

動態樣式(Dynamic Styles)

在本章，我們從頭到尾都用 "動態樣式" 這個詞彙。在Internet Explorer中，樣式的確是動態的，而且隨時都可以被改變，不過這需要靠Script語言才辦得到。程式列表11-14展示了一個利用行內Script程式來改變樣式的例子。23

<HTML>
<HEAD>
<TITLE>Listing 11-14 </TITLE>
</HEAD>
<BODY>
<SPAN STYLE="color:red" onclick="this.style.color='black'">
click me!
</SPAN>
</BODY>
</HTML>
程式11-14
Note

當您透過Script程式來存取樣式時，命名習慣會和CSS習慣用的命名方式有一點不同。因為大部分的Script語言都不允許連字符號 (會被解譯成負數符號)，所以有些CSS屬性名稱，例如font-weight在script語言中就不合法，在這種狀況下，連字符號習慣上都被省略，而將連字符號後的第一個字變成大寫來取代之。因此，font-weight若用在Script語言中則為fontWeight。您可以在 第14章 中找到更多有關命名慣例的資訊。

這個例子加入一個包含文字 "click me!" 的SPAN元件，根據其行內樣式的設定，這段文字在一般狀況下會是紅色的。但是當使用者在SPAN元件上按鈕時，Jscript的事件處理器會先擷取到有click事件發生了，接著會將樣式改變成黑色。因此，當在紅色文字上按鈕時，文字就會變成黑色。 第14章24 將提供完整詳細的技巧，和用Script控制樣式的方法。

目前沒有任何版本的Netscape navigator支援這種方式的動態樣式。在Internet Explorer 3也不支援。因此，程式列表11-14在這些瀏覽器瀏覽時不會改變顏色。

本章提供了動態樣式的概況。在第三部份剩下來的章節中，我們將看看透過樣式來做不同的字體與文字控制，及如何設定網頁中版面與元件位置的配置，最後，再介紹如何使用Script語言來使樣式產生動態的變化。

實戰Dynamic HTML網站技術 視窗縮放
CCS 簡介


實戰Dynamic HTML網站技術=>控制字體與文字樣式

控制字體與文字樣式
小
工
具 加入書架
加入書籤
上一章
下一章

單純的使用HTML都無法讓網頁設計者，對於文字格式做多一點的控制。舉例來說，在未使用樣式表之前，想要讓文字增加雙倍字距、修改字母間距、及設定常用字型等，幾乎不是輕易能做到的。所以串接樣式表 (CSS) 的出現，使得這類型的工作變得十分容易。本章中，我們將會討論一些CSS可提供給我們的工具，這些工具包括如何處理文字、加入字型和文字樣式屬性與嵌入字型 (Font Embedding)。

文字有關的屬性

一些特別會影響字體的CSS屬性 (這些會影響文字個別的字元外觀) 有：font-family，font-style、font-variant、font-weight和font-size。除此之外，font速記屬性(shorthand property) 則能讓您同時地設定多個字型屬性。在圖12-1和12-2中展示的是本章會出現之大部分屬性列表，它們分別在Microsoft Internet Explorer和Netscape Navigator中瀏覽的情況。

1
圖12-1　在Internet Explorer中的一些CSS文字屬性

圖12-2　在Netscape 4.08中的一些CSS文字屬性

程式12-1是一個簡單的例子，教您如何使用這些屬性，它以一個整頁樣式表(Global Style Sheet) 開始，此樣式表為SPAN元件建立一連串的樣式宣告。圖12-3顯示Internet Explorer瀏覽此頁的結果。請注意看看有設定SPAN元件樣式的文字與未設定樣式的文字有甚麼不同。

<HTML>
<HEAD>
<TITLE>Listing 12-1</TITLE>
<STYLE>
  SPAN {
    font-family: "Arial Western"，Verdana，sans-serif;
    font-style:   italic;
    font-variant: small-caps;
    font-weight:  700;
    font-size:    18pt;
  }
</STYLE>
</HEAD>
<BODY>
This sentence is standard text that has no custom style.
This sentence is also standard text that has no custom style.
<HR>
<SPAN>This text uses the custom SPAN style we created.</SPAN>
<HR>
As you can see，some parts of this paragraph <SPAN>use our
custom SPAN style,</SPAN> and some do not. This paragraph
demonstrates how the two types of text can interact and how
line spacing or wrapping can be affected by mixing styles.
</BODY>
</HTML>
程式12-1

2
圖12-3一個利用CSS屬性改變文字的例子

此程式的樣式表中的第一個屬性是font-family，此屬性設定了Internet Explorer的顯示字型。這個屬性設定值是以如下的優先順序設定:

font-family: "Arial Western"，Verdana，sans-serif

這一行程式告訴瀏覽器，如果可以使用Arial Western字型的話就使用此字型；要是系統沒有這個Arial Western字型，則用Verdana來代替；萬一連Verdana也沒有，那麼就只好使用通用字型(generic) sans-serif。Internet Explorer支援五種通用字型：sans-serif、cursive、fantasy、和monospace。常見的字型範例有：Times、Arial、Script、Ransom、和Courier。另外，當字型名稱不只一個字時，則必須用引號括住。目前，Netscape Navigator (至少版本4之前) 並不支援cursive通用字型。

Note

一個serif字型字母的最後一個筆劃會有一條小的垂直線。這些線條，稱為serifs，且其長度、厚度、和彎曲程度皆可改變，所以很多裝飾字型會有長且彎的serifs線條。"sans-serif" 的意思是說 "不使用serifs" 的意思，所以sans-serif字型的字母都是很平順的筆劃，沒有小的垂直線。舉例來說，字母T即顯示成serif字型。請注意serif線條會出現在字母的底部及每個字母頂部的筆劃中。比較來說，這個字母T是sans-serif字型。您可以將serif線條當作是字母的腳，如果在字母的筆劃邊緣有突出來的腳指時，它應該就是serif字型。

在程式12-1的第二個樣式宣告包含font-style屬性，它可以設定成normal、italic、或oblique。一個設定為normal的文字會顯示成roman字型 (此為標準字型)；italic會將文字設定成斜體。基本上， oblique的效果和italic在Internet Explorer中是一樣的；而Netscape Navigator目前則並不支援oblique屬性。

樣式表中的下一個屬性為font-variant，它可以設定成small-caps("small capital letters" 的縮寫) 或normal。若在Internet explorer設定small-caps屬性，則文字會顯示為比一般大寫字母小一點的大寫字母。不過Netscape Navigator也是無法辨識font-variant設定的。3

Note

目前許多CSS屬在Netscape Navigator版本都不被支援。然而Netscape已經宣佈下一個完整版本的Navigator (Netscape 5) 將會盡全力支援CSS1規格。您可以在 webview.com/wr/pub/guides/style/style.html 找到不錯的比較圖表，此圖表比較了不同瀏覽器所支援的各項CSS屬性。名為 "CSS1 Leader Board" 的文章放置在 webview.com/wr/pub/guides/style/board/style.html 中，它能讓您知道CSS1規格在不同瀏覽器中的支援度大概佔了多少百分比例。

您可以利用font-weight來設定字母的粗細，其設定值包括normal、bold、bolder、或lighter，其中normal是預設值。基本上，bold設定會使得文字比預設更粗(或更黑)；bolder則使文字更粗；而lighter設定會使文字比預設值更細。您可以使用範圍100到900的來設定個別粗細設定值，每次增加100。其中900是最粗的，400為預設值，而700通常相當於設定成bold。

使用在程式12-1的font-size屬性，將可以讓您控制字型大小。您可以利用下列方式來設定這個屬性:4

  • 使用一個精確的大小，例如1pt。參考稍後本章度量單位 (Unit of Measurement) 的這段說明。
  • 使用一個相對於預設值的百分比大小。舉例來說，一個200% 設定讓可以文字變成正常的兩倍大小。
  • 使用一組關鍵字。可以用的關鍵字是xx-small、x-small、small、medium、large、x-large和xx-large。這些值相對於使用者在字型外觀的設定值。
  • 使用兩個相對的關鍵字larger和smaller。這些值都相對於父元件的大小。

最後注意在程式12-1我們所設定的樣式定義:

SPAN {
       font-family:	"Arial Western"，Verdana，sans-serif;
    font-style:	italic;
    font-variant	small-capsl;
    font-weight":	700;
    font-size :	18pt;
}

如果我們使用font速記屬性來替代，我們可以使用下面這段程式來設定相同的定義:5

SPAN {
    font:small-caps italic 700 18pt "Arial Western"，Verdana，sans-serif;
}

正如您所看到，使用font速記屬性的確可節省不少打字的功夫。不過，正如同您在 第11章 所學到的，速記屬性中的屬性值必須依照特定的順序排列。當您使用font速記屬性時，有三個屬性設定：font-style、font-variant和font-weight必須在所有其他字型屬性之前 (雖然三個屬性誰先出現並不重要) ，不過這些屬性是可有可無的。後面接著的font-size設定則是需要的。此外，您也可將一個選用的line-height設定加進來 (我們將在下一段中討論這個屬性)。其餘可選用的屬性，如果不需要時，您可輕易地將它們省略。

文字的屬性

目前我們所介紹的屬性都允許我們控制個別字元的外觀。某些其它的CSS屬性可讓您改變一組字元的顯示。包括text-decoration、text-transform、text-align、text-indent、letter-spacing和line-height。此外，color屬性在文字中也十分常用。程式12-2展示這些屬性如何運作，且您會在下面的網頁中看到結果。

<HTML>
<HEAD>
<TITLE>Listing 12-2</TITLE>
<STYLE>
  DIV {
    text-align: justify;
    text-indent: 2em
  }
  SPAN {
    text-decoration: underline;
    text-transform: uppercase;
    vertical-align: super;
    letter-spacing: .5em;
    line-height: 200%;
    color: red
  }
</STYLE>
</HEAD>
<BODY>
These first two sentences are just standard text that has no
custom style. We have created style rules for SPAN and DIV
elements.
<HR>
Some more standard text.
<SPAN>This text uses the custom SPAN style we created.</SPAN>
<HR>
More standard text.
<DIV>
This whole paragraph is inside a DIV element. <SPAN>This
sentence is in a SPAN，which is in the DIV.</SPAN> This
paragraph demonstrates that DIV is a block element and SPAN
is an in-line element. Notice how the styles interact.
</DIV>
</BODY>
</HTML>6
程式12-2

圖12-4　一個使用CSS屬性來設定文字樣式的例子

程式12-2同時使用了SPAN和DIV元件。使用樣式設定時，這兩個元件都十分有用，並且兩者不同地方的區分非常重要。SPAN是一個行內(in-line) 元件，這個意思是說一個SPAN元件可以直接嵌入在文字之間且前後沒有換行(line break)；它跟隨著段落走，就像是段落中的其他文字一樣。一些其他常見的行內元件是B (粗體) 、U (加底線)和I (斜體)。相對地，DIV是一個區塊(Block)元件。區塊元件並不跟段落中其他文字一樣跟隨著段落走，相反地，DIV元件被視為一個分隔的文字區塊，且本質上就自成一個段落。一些其他常見的區塊元件是P (段落) 、HR(水平分隔線) 、TABLE和清單列表元件，例如UL、OL和LI。而每個區塊元件都會在前面加上一個換行符號。DIV和SPAN並不是設定文字格式的元件，不像B或LI。程式12-2使用一個DIV元件，因為text-align和text-indent屬性只能使用在區塊元件上。

Note

很多CSS屬性只能使用在區塊元件。大部分屬性的詳細描述，包含它們的線上顯示效果和區塊元件，都可以在SBN Workshop網站和書附光碟中找到。在CD中，參考Workshop(References); DHTML，HTML，& CSS;CSS; CSS Attribute Refrence。想要取得線上版本，請連至MSDN線上資源網頁 msdn.microsoft.com/resources/schurmandhtml.htm ，或在書附光碟中開啟檔名為MSDN_OL.htm的網頁，然後選擇CSS Attributes。想要學習更多有關CSS的資訊，請連至網站7 www.w3.org/Style/ 。CSS1規格可在 www.w3.org/TR/REC-CSS1 中找到。

text-align屬性可控制一個區塊文字(如一個DIV元件，或P元件) 的對齊位置。您可以將這個屬性設定為left、right、center、或justify。當設定成left，會將文字調整到左邊 (平均地將每行文字靠文字區塊的左邊對齊)；設定成right，會將文字調整到右邊；設定center，則會將文字區塊中的每行文字都居中；若將text-align設定成justify ，則文字會靠左右對齊，且將文字間距均分 (就像您在本書看到的字距配置一樣)。

text-indent屬性會決定第一行文字段落縮排的距離。這個屬性可使用標準的度量單位，例如em和px及百分比表示法。您甚至可以設定一個負數值，以產生一個懸掛縮排 (hanging indents)。這個屬性使用在p元件時特別好用，因為它允許您為網頁上的每一個段落建立第一行的縮排。

程式12-2也包括5個其他格式的屬性。第一個屬性，text-decoration，可以設定成underline、overline、line-through、blink、或none。其中underline、overline、line-through會在文字的不同高度位置上畫線 (在文字之下、之上、及從中間穿過畫線)。Netscape Navigator 4並不支援Overline設定。而blink設定在Internet Explorer 4或5並不會顯示出來。您可將text-decoration設定成none，來關閉文字上存在的任何裝飾文字設定。舉例來說，下面對於錨元件A (Anchor) 的樣式定義，可將超連結原本有的底線取消設定：8

A { text-decoration: none }

text-trnasform屬性可控制文字的大小寫。其設定值與設定效果如下所示：

  • capitalize 將每一個字的第一個字母變成大寫
  • uppercase 將所有字母變成大寫
  • lowercase 將所有字母變成小寫
  • none 重設任何繼承的大小寫設定，回復原來的設定值

vertical-align屬性可讓您設定下標字 (subscript) 與上標字 (superscript)，其可能的設定值是sub和super。這個屬性並不允許您設定從基線 (base-line) 開始，將文字移動某個精確的距離。不過，利用相對定位 (relative positioning) 倒是可完成這項功能，這部份我們將在下一章討論。9

letter-spacing屬性會控制文字中每個字母之間的距離，以一般度量表示法表示成px或em。em單位在此處特別有用，因為它可以改變字母距離，而此距離相對於使用的字型大小。

因為line-height屬性可決定文字行的大小，包括字元上下方應保留的距離，也就是說此屬性有設定行距(line spacing)的效果。您可以利用設定一個長度 (雖然任何度量單位都可支援，但一般都是用點或ems)、百分比、或一個數字來指定此屬性(十進位數字就可以使用)。下列的樣式宣告具有相同的效果:

DIV { font-size:10pt; line-height:20pt}
DIV { font-size:10pt; line-height:2em}
DIV { font-size:10pt; line-height:2}
DIV { font-size:10pt; line-height:200%}

在程式12-2中最後使用的屬性color，可設定DIV中的文字顏色。您可以從顏色表中挑出一個預先定義的顏色來設定此屬性，例如：black或red (完整的顏色表格可在SBN Workshop網站和書附光碟中找到。在光碟中，請參考 Wotkshop(Refrences);DHTML，HTML & CSS;DHTML Refrences;Color Table。想要取得線上版本，連上MSDN線上資源網站 msdn.microsoft.com/resources/schrumandhtml.htm )，或開啟書附光碟中檔案名稱MSDN_OL.htm和選擇DHTML Color Table)。您也可以使用RGB十進位的三連字元表示法或RGB 16進位三連字元表示法來設定顏色。RGB三連字元讓您指定紅(Red)，綠(Green)，和藍(Blue) 組成的顏色，每個組成顏色設定值範圍由0到255 (十進位數)，或00到ff (16進位數)。因此，下面的三個樣式定義會得到相同的結果:

SPAN {color: blue}
SPAN {color: rgb(0,0,255)}
SPAN {color: #0000ff}10

度量單位(Units of Measurement)

就像剛剛看到的這些例子所示，您可以使用不同的標準度量單位來設定樣式中長度或大小。而Internet Explorer如何顯示這些不同型態的度量單位及瀏覽器支援的單位為何，如下圖所示：

嵌入字型(Font Embedding)

FONT元件和CSS font-family屬性允許您指定顯示一種字型，但是它只能指定使用者已經有的字型。而無法保證使用者一定會安裝想要顯示的字型。透過 @font-face屬性嵌入字型，可讓您指定任何想使用的字型，且確定能保證使用者一定會用嵌入字型來顯示網頁文字，因為它會用暫時安裝的方式指定給使用者的電腦。W3C已正式將 @font-face屬性納入CSS level-2規格中。

可惜的是，Netscape Navigator目前沒有任何一個版本可支援 @font-face屬性。不過Netscape Navigator倒是支援一個由Bitstream公司開發的字型嵌入通訊協定， 稱之為TrueDoc。Bitstream也已經釋出一個可下載的Microsoft ActiveX控制項，它可在Internet Explorer 4及更新版本中加入TrueDoc的支援。然而，TrueDoc並不是W3C所提出CSS規格書的一部份，且也不在本書所涵蓋的範圍。有關TrueDoc的詳細資訊可以在 www.truedoc.com11 找到。

如何嵌入字型

建立嵌入字型的網頁是容易的。建立網頁的第一步就是指定您想要的字型 (這些字型必須可以在該機器中使用)。程式12-3產生一個簡單的網頁，此網頁指定三個字型，而沒有使用嵌入字型技術。圖12-3展示Internet Explorer如何顯示這個程式碼。

<HTML>
<HEAD>
<TITLE>Listing 12-3</TITLE>
<STYLE>
  .crl {font-family: "Curlz MT"}
  .viv {font-family: "Vivaldi"}
  .stp {font-family: "Stop"}
  DIV  {font-size: 30pt}
</STYLE>
</HEAD>
<BODY>
<DIV CLASS="crl">This is some text using Curlz MT</DIV>
<DIV CLASS="viv">This is some text using Vivaldi</DIV>
<DIV CLASS="stp">This is some text using Stop</DIV>
</BODY>
</HTML>
程式12-3

圖12-5　這個網頁指定的三種字型都是在目前電腦中無法顯示的字型12

如果使用者要觀看這個網頁，而電腦中並沒有安裝這些特定的字型(可能這些字型比較不常見)，則網頁就不能正確的被顯示。在圖12-5的視窗中顯示的網頁，是從沒有安裝這些特定字型的電腦中瀏覽的。注意所有在標準瀏覽器字型中的文字，並不是我們想要看到的網頁字型。

為了建立下載字型檔案且將這些字型嵌入到網頁中，如此網頁才能像我們想要看到的樣子，我們使用一個工具名稱為WEFT，它代表網頁嵌入字型工具(Web Embedding Font Tools)。這些工具可在書附光碟中的 \tools\msweft.exe檔案或 www.microsoft.com/typography 中找到。WEFT將會分析此網頁，決定要使用哪些字型，建立這些字型的嵌入字型版本，且接著若需要的話，修改原來的網頁使其可呼叫這些字型。程式12-4展示在WEFT處理完成之後，此網頁原始碼會變成有何改變。圖12-4顯示此網頁的瀏覽結果 (此頁標題還是Listing 12-3，因為工具並無修改此行)。

WEFT會嵌入允許使用字型的檔案之位置，也嵌入字型的位置及嵌入字型本身。為了安全考量的理由，字型檔只能使用在特定路徑中。因為使用字型檔案被限制，所以讓想要竊取字型來另做它用的風險降到最低。程式12-4，允許的路徑為D:\chap12\ 。如果您要試一下書附光碟中的這個例子，您的CD-ROM路徑必須是D: 磁碟機，如果您計劃使用在網站伺服器中一個EOT檔案，您必須將WEFT指向一個網站伺服器的位置，當WEFT產生字型時。這確定所產生的路徑將指向您的網站伺服器且字型可以在此使用。您也許會需要拷貝所建立的字型到網站伺服器中。若您想實驗性質一下將字型建立在您的電腦中，則可使用file:// 協定；例如：file://D:\Chap12\CURLZMT9.eot。若您實際去使用了WEFT這個工具，這些設定您應該就會變得更清楚了!

<HTML>
<HEAD>
<TITLE>Listing 12-3</TITLE>
<STYLE>
  .crl {font-family: "Curlz MT"}
  .viv {font-family: "Vivaldi"}
  .stp {font-family: "Stop"}
  DIV  {font-size: 30pt}
</STYLE>
<STYLE TYPE="text/css">
<!--
  @font-face {
    font-family: Curlz MT;
    font-style:  normal;
    font-weight: normal;
    src: url(file://d:\chap12\CURLZMT0.eot);
  }
  @font-face {
    font-family: Vivaldi;
    font-style:  normal;
    font-weight: normal;
    src: url(file://d:\chap12\VIVALDI0.eot);
  }
  @font-face {
    font-family: Stop;
    font-style:  normal;
    font-weight: normal;
    src: url(file://d:\chap12\STOP0.eot);
  }
-->
</STYLE>
</HEAD>
<BODY>
<DIV CLASS="crl">This is some text using Curlz MT</DIV>
<DIV CLASS="viv">This is some text using Vivaldi</DIV>
<DIV CLASS="stp">This is some text using Stop</DIV>
</BODY>
</HTML>
程式12-413

圖12-6　顯示所想要的嵌入字型

建立可用來下載的字型檔會有EOT的附檔名，這樣網頁才能正常地找到字型，此外，請確定WEFT所建立的EOT檔案是放在HTML文件所指定的目錄中。

被修改的網頁不只包含我們原本就包含在檔案中的字型參考，也包含一連串 @font-face樣式規則，它會告訴瀏覽器到哪裡去找字型檔案。雖然WEFT對於建立一個嵌入字型是蠻需要的，不過您也可以直接手動加入這些 @font-face規則。注意版本1的WEFT有時候對於多個字的字型名稱會有問題。

設定可使用字型(Font Availability)

一些設計字型的公司會對於購買字型者限制其中一些字型的使用。因此，您不能假定任何安裝在您的電腦中的字型，都能分享給您的網頁使用。TrueType字型是以嵌入許可 (Embedding Permisson) 來編碼的，而這個許可是利用有如WEFT此種允許使用字型之轉換工具來建立的。四種許可等級請參考表格12-1。

NOTE

Microsoft維護一個討論網頁字型(Web Typography) 資訊的特定網站，想要看Microsoft如何處理Web-based字型的領域，請連上14 www.microsoft.com/typography 這個網址。本書撰寫之時，WEFT版本2的beta版已經可以在網站找到。

表12-1　四種嵌入字型的許可等級
存取等級 | 說明
No embedding | 建立字型者並不允許它們的字型被嵌入。(不過，通常建立字型者會提供不同程度可嵌入的版本)15
Print and Preview | 這些字型可以被嵌入，只有當此網頁對於使用者是靜態的。換句話說，這個網頁使用的字型是不能被使用者編輯的 (舉例來說，就像一個Web-based e-mail編輯器一樣)。
Editable | 這些字型不但可以嵌入，且也沒有列印與預覽字型的限制。
Installable | 這些字型被視為可以在Internet Explorer中被編輯，所以它們可以被當做一般字型來使用。雖然它們有可安裝的許可等級，Internet Explorer並沒有安裝這些字型到使用者的字型資料夾。因為使用者可能會透過網站處理數以百計的字型，這個限制幫助避免一些不想的字型來搗亂使用者的電腦。

在WEFT中，您可以輕易地決定您電腦中所有字型的許可等級，只要在View選單選擇Avaiable Fonts。WEFT會檢查您的系統中所有的字型，且顯示一個如下圖所示的報告 (Report)，它會告訴您字型是否可以嵌入，或是否為Windows的核心字型，是否損壞，或字型狀態是否未知。16

實戰Dynamic HTML網站技術 視窗縮放
控制字體與文字樣式


實戰Dynamic HTML網站技術=>利用樣式表來控制版面與位置

利用樣式表來控制版面與位置
小
工
具 加入書架
加入書籤
上一章
下一章

在 第12章 中，您已經知道CSS屬性和樣式表是如何同時影響網頁上的字型和其它文字特性了。其實，樣式也可以用來設定元件的格式和位置，並控制整個網頁的版面設定。舉例來說，您使用CSS可以完成下列工作：

  • 在元件後面設定背景圖案與顏色。1
  • 建立環繞在區塊文字外的邊框(border) 。
  • 為圖形設定不同的上、下、左、右邊界(margin) 。
  • 精確地調整物件與邊框之間的距離。
  • 將物件放置在螢幕上以像素(pixel)為基準的位置上。
Note

本章中介紹的許多樣式屬性都不能正常地顯示在Netscape Navigator 4中，但根據可靠消息來源指出，Netscape 5將會儘可能地支援CSS規格，以正常顯示大部分的樣式。

格式化元件

當您在設計版面及格式化元件的時候，可以想像元件是被「格式化區域」(formating regions)所包圍，因為這種想法對於版面設計蠻有用的。在這些區域中，您可以想像元件的後面是背景 (background)；而邊界留白(padding) 則分隔了元件與邊框 (Border)；至於邊界 (margin)則位於邊框的外面，以與其他元件分隔。對於上述元件 (邊界留白padding、邊框border、邊界margin ) 各自都有它的top、bottom、left和right屬性，雖然不是所有區域格式化的屬性都能適用於所有元件，不過您還是會覺得它們蠻有用的。下面是個元件格式化區域的示意圖。2

背景屬性

底下我們來看看5個會影響元件背景的CSS屬性，分別是：background-color、background-image、background-repeat、background-position和background-attachment。此外，還有一個background速記屬性，可讓您同時設定所有的背景屬性。

我們的第一個例子，程式13-1簡單的展示了如何使用background-color屬性來指定元件的背景顏色。圖13-1顯示的是瀏覽結果。

<HTML>
<HEAD>
<TITLE>Listing 13-1</TITLE>
</HEAD>
<BODY>
<DIV>This has no style set.</DIV>
<DIV STYLE="background-color: red">
  This has background-color set.
</DIV>
</BODY>
</HTML>
程式13-1

3
圖13-1　您可以使用background-color屬性來改變元件的背景顏色

background-color屬性接受任何標準的顏色表示法來當作設定值，包括：顏色表(color Table)中的顏色名稱、RGB十進位三連字元、或RGB十六進位三連字元 (參考 第12章 )。如果想要使用顏色表預先定義的顏色，可參考SBN Workshop網站或書附光碟。請參考在光碟中的Workshop (References); DHTML，HTML & CSS; CSS ; DHTML References;然後選擇Color Table。想獲得線上版本，則請連至MSDN線上資源網站 msdn.microsoft.com/resources/schurmandhtml.htm ，或開啟書附光碟中的MSDN_OL.htm，然後選擇Color Table。想要獲得更多的CSS屬性資訊，在CD中可以到Workshop(References);DHTML，HTML，& CSS;CSS，CSS Attributes Reference。

如果您偏好在元件背後顯示一個背景圖形，而非只是一個單調的顏色，您可以選擇使用background-image屬性。程式13-2為第二個DIV元件設定了一個圖形背景，我們可以在圖13-2中可以看到結果。4

<HTML>
<HEAD>
<TITLE>Listing 13-2</TITLE>
</HEAD>
<BODY>
<DIV>This has no style set.</DIV>
<DIV STYLE="background-image: url(tile.gif)">
  This has background-image set.
</DIV>
</BODY>
</HTML>
程式13-2

圖13-2　您可以使用background-image屬性來改變元件的背景圖形

background-image屬性有兩個可能的設定值：none和url(Uniform Resource Locator)。將background-image設定成none時，會除去之前所設定的圖形。這個屬性通常都是在要透過script來動態改變背景時使用。當您將background-image設定為url時，則必須用括弧將所要顯示的圖檔名稱與位置括起來，如程式13-2所示。

當您指定了檔案位置，您可以設定目標檔案為絕對或相對路徑。絕對路徑提供的是完整的檔案位置，例如， http://www.microsoft.com/library/images/gifs/toolbar/home.gif5 。相對路徑提供的則是相對於呼叫檔案的資源位置。舉例來說，若兩個檔案都放在同一個目錄，則您只要設定目標檔名就好。若目標資源檔案放置在子目錄時，則必須在子目錄名稱後面，加上一條反斜線及目標檔名。您可以透過兩個點符號來參考到前一層的目錄。因此，若一個目錄包含兩個子目錄：data和images，則在data目錄的HTML檔案，其background-image屬性要設定成參考到放在images目錄下的a.gif檔案時，其程式碼即為url(../images/a.gif)。若要參考的檔案與想要呼叫的網頁在同一個網站伺服器中，則只要目錄名稱之前加上反斜線即可。例如，任何在microsoft.com網站上的網頁，要參考microsoft.com/images/a.gif這個檔案時，即可表示成url(/images/a.gif)。

當元件使用背景圖形時，圖形將會有很多不同效果的重複顯示的方法。程式13-3提供了如何使用background-repeat屬性的一些例子。您可以在圖13-3中看到不同的視覺效果。

<HTML>
<HEAD>
<TITLE>Listing 13-3</TITLE>
<STYLE>
  DIV {background-image: url(tile.gif); height: 44; width: 230}
</STYLE>
</HEAD>
<BODY>
<DIV>
  A global style sheet sets background-image for the
  DIV element.
</DIV>
<BR>
<DIV STYLE="background-repeat: repeat">
  This DIV has background-repeat set to repeat.
</DIV>
<BR>
<DIV STYLE="background-repeat: no-repeat">
  This DIV has background-repeat set to no-repeat.
</DIV>
<BR>
<DIV STYLE="background-repeat: repeat-x">
  This DIV has background-repeat set to repeat-x.
</DIV>
<BR>
<DIV STYLE="background-repeat: repeat-y">
  This DIV has background-repeat set to repeat-y.
</DIV>
</BODY>
</HTML>
程式13-3

圖13-3　您可以使用background-repeat屬性來重複背景圖形
Note

在使用background-image屬性時，若能同時設定background-color屬性，將不失為一個好習慣 (例如，STYLE="background-image:url(tile.gif);background-color:red")。因為，萬一瀏覽器不能顯示背景圖形或找不到圖檔時，就可以用指定的背景顏色來代替。本章稍後，您將會看到如何使用background速記屬性來簡化程式碼。6

預設的backgroud-repeat屬性值為repeat，它會讓background-image屬性中所設定的圖形重複顯示在整個元件中。這個設定對於想要產生連續小圖示的背景來說，十分有用。若只想顯示一個背景圖檔，則可將background-repeat設定成no-repeat。至於repeat-x可讓圖形只在水平方向重複，而repeat-y則可設定讓圖形只在垂直方向重複。

此外，您可以使用background-position屬性，來指定背景圖案相對於元件的起始位置，也就是指定背景圖形在元件後面的水平和垂直位置。程式13-4和圖13-4示範了這個屬性的各種設定值，及每種設定值如何影響背景圖案的位置。

background-position屬性可接受關鍵字包括：設定水平位置的left、center、和right；及可設定垂直位置的top、center和bottom。或者也可以使用px(pixels)一類的標準度量單位以及百分比 (請參看 第12章 中標準度量單位的列表)。這個屬性在處理BODY元件時可是十分有用的。例如，您可以將一個圖形設定為在整個網頁背後居中，也就是將BODY元件的background-position屬性設定為center center，讓圖形在水平與垂直方向都能置中。

<HTML>
<HEAD>
<TITLE>Listing 13-4</TITLE>
<STYLE>
  DIV {background-image: url(tile2.jpg); height: 75;
         width: 275;
       border: solid 1px black; float: left; margin: 5px}
</STYLE>
</HEAD>
<BODY>
<DIV>
  A global style sheet sets background-image, width, and height
  for the DIV element. This uses the default background-position.
</DIV>

<DIV STYLE="background-position: bottom right">
  This DIV has background-position set to bottom
  right
</DIV>

<DIV STYLE="background-position: 25% 10px; background-repeat: no-repeat">
  This DIV has background-position set to 25% 10px and
  background-repeat set to no-repeat.
</DIV>

<DIV STYLE="background-position: center center">
  This DIV has background-position set to center center.
</DIV>
</BODY>
</HTML>
程式13-47

圖13-4　您可以使用background-position屬性來控制背景圖形的位置

background-attachment屬性只能使用在BODY元件中，指定背景圖形是否與網頁其他部分一起捲動。其中，scroll是此屬性的預設值。如果希望使用者捲動捲軸時，網頁元件也能在背景捲動，可將background-attachment設定成fixed。不過，Netscape Navigator 4並不支援這個屬性。

為了能同時設定所有這些和背景相關屬性，您可以使用background速記屬性。不過個別屬性必須依下列順序來設定：background-color、background-image、background-repeat、background-attachment和background-position。這些屬性都是選用的，因此可隨時刪除其中一個不想要用的屬性。我們來看一個使用背景屬性的樣式定義範例：

DIV {
    background-color:red;
    background-image:url(tilt.gif);
    background-repeat:no-repeat;
    background-position: center center;
}

這個樣式定義可以簡化成下面這行程式碼:

DIV {background: red url(tile.gif) no-repeat center center}8

邊框屬性

CSS可以允許您對於元件的邊框 (一條看得見且環繞在元件的部份或全部的框線) 做精確的控制。您可以同時設定每一個邊框的線條厚度、樣式、與顏色，或者您也可以個別設定每一個邊框的特性。

border-width屬性定義的是環繞在元件外面的邊框厚度。這個屬性可用的關鍵字為：thin、medium和thick，此外，也可以使用標準度量單位的敘述方式，例如px、em和pc。注意medium和thick設定值顯示在Netscape Navigator 4中時，看起來會比在Microsoft Internet Explorer厚一些。在程式13-5中，我們針對一些邊框使用了不同的設定，圖13-5顯示了這些不同設定的結果。

<HTML>
<HEAD>
<TITLE>Listing 13-5</TITLE>
<STYLE>
  DIV {border: groove red}
</STYLE>
</HEAD>
<BODY>
<DIV STYLE="border-width: thin">border-width of thin.</DIV>
<BR>
<DIV STYLE="border-width: medium">border-width of medium.	</DIV>
<BR>
<DIV STYLE="border-width: thick">border-width of thick.</DIV>
<BR>
<DIV STYLE="border-width: 10px">border-width of 10px.</DIV>
<BR>
<DIV STYLE="border-width: 1em">border-width of 1em.</DIV>
</BODY>
</HTML>
程式13-5

圖13-5　利用border-width屬性，您可以改變邊框的厚度9

border-style屬性可以定義環繞在元件外面的邊框樣式。可設定的關鍵字為：none、solid、groove、ridge、inset和outset (inset和outset邊框樣式通常無法在256色中正常顯示，因為其中間顏色調配的不好)。程式13-6提供一個展示這些效果的例子，如圖13-6所示。

<HTML>
<HEAD>
<TITLE>Listing 13-6</TITLE>
<STYLE>
  DIV {border: 9px red}
</STYLE>
</HEAD>
<BODY>
<DIV STYLE="border-style: none">border-style of none.</DIV>
<BR>
<DIV STYLE="border-style: solid">border-style of solid.</DIV>
<BR>
<DIV STYLE="border-style: double">border-style of double.</DIV>
<BR>
<DIV STYLE="border-style: groove">border-style of groove.</DIV>
<BR>
<DIV STYLE="border-style: inset">border-style of inset.</DIV>
<BR>
<DIV STYLE="border-style: outset">border-style of outset.</DIV>
<BR>
</BODY>
</HTML>
程式13-6

圖 13-6木利用 border-style 屬性，您可以改變邊框的樣式

border-color屬性同時設定四個邊框的顏色。它接受和background-color屬性 (在前段討論過了) 一樣的標準顏色設定。一些邊框樣式，例如groove、inset和outset，都由不同顏色組成，以建立一個三度空間的效果。這些邊框樣式使用border-color設定為基底顏色，不過可能會增加陰影或淡化顏色以加強3-D效果。

您可以使用border速記屬性同時設定整個邊框的width，style和color，來代替分別設定border-width、border-style和border-color屬性。正如同程式13-7所示。結果的邊框顯示在圖13-7。10

<HTML>
<HEAD>
<TITLE>Listing 13-7</TITLE>
<STYLE>
  DIV {border: 10px double red}
</STYLE>
</HEAD>
<BODY>
<DIV>This has the same border on all sides.</DIV><BR>
</BODY>
</HTML>
程式13-7

圖13-7　您可以使用border速記屬性一次設定width 、style、和整個邊框的顏色

所有包含在border速記屬性的屬性都是可有可無的，且可以按照任何順序。如果您省略其中一個屬性設定，Internet Expolorer會顯示該屬性的設定值。舉例來說，如果您省略顏色設定，則邊框顏色將會是預設的黑色。有一個重點必須要注意的：如果您省略border-style設定，則Internet Expolrer會使用預設值none，表示不需顯示邊框。

border-left、border-right、border-top和border-bottom屬性讓您一次設定單一邊框的厚度、樣式、和顏色。這些屬性在Netscape Navigator 4中並不被支援。底下的程式13-8中展示了如何為元件的每一邊設定不同的邊框。而圖13-8展示結果的網頁。

<HTML>
<HEAD>
<TITLE>Listing 13-8</TITLE>
<STYLE>
  DIV {
    border-top: 10px double black;
    border-bottom: none;
    border-left: 20px solid red;
    border-right: 15px groove green;
  }
</STYLE>
</HEAD>
<BODY>
<DIV>This has a different border on each side.</DIV>
</BODY>
</HTML>11
程式13-8

圖13-8　此元件的每一邊都有不同的邊框

您甚至也可以使用更多特定的CSS屬性，微調邊框某一個特定性質的設定。這些屬性在Netscape Navigator 4中並不被支援 (目前在Internet Explorer和Opera (一個小又快速且只需要1 MB磁碟空間的瀏覽器) 中都已支援，而未來在Navigator 5中也很有可能會支援)。這些屬性包括:

border-left-width | border-right-width | border-top-width12 | border-bottom-width
border-left-style | border-right-style | border-top-style | border-bottom-style
border-left-color | border-right-color13 | border-top-color | border-bottom-color

這些屬性可以混用及針對想要的效果來使用。舉例來說，下面的樣式定義建立一個10-pixel寬的紅色雙邊框，不過其左邊是沒有邊框的，而且底部的邊框也只有5 pixel厚。

DIV { border:10px double red; border-left-style:none;
          border-bottom-width: 5px }

邊界留白與邊界屬性

包圍在元件周圍的空間是由邊界留白(padding)和邊界(margin) 屬性來控制的，其中padding屬性可設定元件與邊框之間的空間；margin屬性則可設定邊框與其他元件之間的空間。其他額外及特定的屬性，例如padding-right和margin-top則允許您針對單一邊框設定不同大小的邊界留白與邊界。

程式13-9展示幾個主要版面配置的屬性，包含padding和margin。這兩個DIV元件有淺灰的背景顏色，其背景透過20 pixel的留白，延伸到10 pixel寬的藍色實心邊框。這兩個邊框以30 pixel的邊界來分隔。在圖13-9中，我們可以看到其顯示結果。同樣的程式碼若顯示在Netscape Navigator 4.08中，元件的邊界留白與邊界間會有一個微小的間隙(因此網頁的背景顏色會顯示出來)。這表示雖然Netscape 4也支援padding和margin，不過它的運作方式並不完全符合CSS規格。這個問題在Netscape 5中將可能會被修正。14

<HTML>
<HEAD>
<TITLE>Listing 13-9</TITLE>
<STYLE>
  DIV {
    padding: 20px;
    margin: 30px;
    background: darkgray;
    border: 10px solid black;
    height: 50px;
    width: 300px
  }
</STYLE>
</HEAD>
<BODY>
<DIV>
  A global style sheet sets many attributes for the DIV
  element.
</DIV>
<DIV>
  A global style sheet sets many attributes for the DIV
  element.
</DIV>
</BODY>
</HTML>
程式13-9

圖13-9　padding和margin屬性控制圍繞一個元件外的空間

網頁的版面配置

除了目前所討論的屬性之外，CSS也提供一些屬性，讓您可以控制：元件的顯示與否、元件在螢幕上的位置、以及每個元件的相對位置。

平面空間的位置屬性15

CSS定位(CSS Positioning)，也稱為CSS-P，是正式的CSS2規格的一部份。元件主要的定位工具是：position、top和left屬性，這些屬性展示在程式13-10中，並且在圖13-10中顯示其結果。

top和left屬性設定使用的是標準的CSS度量單位，分別用來指定元件與其上邊界及左邊界的距離 (定義為元件邊界的邊緣) 。基本上，這些距離以基點(base point)做為位置參考點，而基點則是由position屬性來設定。請注意要使用top或left屬性，一定要先設定position屬性。

<HTML>
<HEAD>
<TITLE>Listing 13-10</TITLE>
<STYLE>
.span1 {position: absolute; top: 0px; left: 0px;
        background: blue}
.span2 {position: absolute; top: 25%; left: 25%;
        width: 50%;
        background: lightgrey}
.span3 {position: relative; top: 3px;
        background: red}
.span4 {position: absolute; top: 75px; left: 25px;
        width: 50%;
        background: green}
</STYLE>
</HEAD>
<BODY>

<SPAN CLASS="span1">SPAN #1 has position set to absolute.
</SPAN>

<SPAN CLASS="span2">
  SPAN #2 has position set to absolute.
  The following word <SPAN CLASS="span3">relative</SPAN>
  is in SPAN #3，which has position set to relative.

  <SPAN CLASS="span4">
    SPAN #4 is contained by SPAN #2 and has position
    set to absolute.
  </SPAN>

  This is the last text in SPAN #2
</SPAN>
</BODY>
</HTML>
程式13-10

圖13-10　使用position、top和left屬性來為網頁上的元件定位

postion屬性的三種可能設定值為：static、absolute和relative。其中static為預設值，表示瀏覽器會將元件定位在一般的位置上，而忽略top和left屬性的設定。16

將position設定為absolute，能讓您將元件放置在相對於其父元件 (即包含此元件的元件)左上角某個距離的位置上。舉例來說，在程式13-10中，SPAN #1的父元件就是BODY元件，或者你也可以說就是整個網頁。將position設定成absolute，並將top和left設定為0，則可將此SPAN元件放置在網頁的左上角。由於SPAN #4的父元件是SPAN #2，所以它的top和left屬性值是以SPAN #2的左上角為準，而非BODY元件。

至於relative設定值，可以讓您將元件定位在相對於目前位置某個特定距離的位置上。使用相對定位，SPAN #3可以放在比基準位置低3 pixel的位置上。

Note

程式13-10在不同的瀏覽器中會有不同的顯示結果。任何時候在您設定定位屬性時，最重要的事就是必須在各種瀏覽器中進行測試。

通常我們都會以為absolute和relative設定的不同在於：absolute是用pixels來設定距離，而relative則是以百分比來設定距離。這是一個錯誤的想法，因為不管是absolute和relative，都可以用pixels和百分比當作其度量單位。

三度空間的位置屬性

透過定位方式，要將網頁中的兩個元件放在同一個位置是可以做到的。一般來說，列在HTML程式碼的最後一個元件會顯示在網頁的最上層。您可以利用z-index屬性來將此元件放到另一個元件的前面或後面。程式13-11提供了設定z-index屬性的例子。在圖13-11中，您可以看到這些不同的效果。

在程式13-11，我們用到兩個圖形及一個包含文字的SPAN元件。SPAN元件的z-index屬性設定為0，而兩個圖形的z-index屬性則分別設定成 -1和1。其中，z-index設為1的圖形會顯示在SPAN文字(z-index為之0) 上方；而z-index設為 -1的圖形則會顯示在這段文字的背後。就跟top和left一樣，z-index屬性也只能在position屬性值為absolute或relative時使用，雖然Navigator 4瀏覽器在顯示此網頁時會有問題，不過，Navigator 5應該會支援z-index。17

<HTML>
<HEAD>
<TITLE>Listing 13-11</TITLE>
<STYLE>
  .img1  {position: absolute; top: 100px; left: 150px;
          z-index: 1}
  .span1 {position: absolute; top: 90px; left: 60px;
          z-index: 0}
  .img2  {position: absolute; top: 100px; left: 330px;
          z-index: -1}
</STYLE>
</HEAD>
<BODY>
<IMG CLASS="img1" SRC="one.gif" >
<SPAN CLASS="span1">
  This SPAN has a z-index value between those of the two images.
</SPAN>
<IMG CLASS="img2" SRC="two.gif">
</BODY>
</HTML>
程式13-11

圖13-11　您可以使用z-index屬性來放置元件至其他元件之後

display與visibility屬性

目前為止，您應該已經學會如何在網頁中放置元件了。display和visibility屬性則是讓您控制元件是否要顯示在網頁上。下一頁的程式13-12中會使用到這兩種屬性。而下一頁的圖13-12則展示了在Internet Explorer中的顯示結果。

<HTML>
<HEAD>
<TITLE>Listing 13-12</TITLE>
</HEAD>
<BODY>
<IMG SRC="one.gif" STYLE="visibility: visible">
<IMG SRC="two.gif" STYLE="visibility: hidden">
<IMG SRC="three.gif">
<IMG SRC="four.gif" STYLE="display: none">
<IMG SRC="five.gif" STYLE="display: inline">
<IMG SRC="six.gif" STYLE="display: block">
<IMG SRC="seven.gif" STYLE="display: list-item">
</BODY>
</HTML>18
程式13-12

圖13-12　display與visibility屬性讓您控制是否讓元件顯示在網頁上

display和visibility屬性可以允許您不讓元件顯示出來。只要將visibility屬性設定為hidden，即可將該元件變成隱形，雖然元件仍然會佔據視窗上的空間。visibility屬性的預設設定值為visible，這表示元件會顯示出現，並且跟一般元件一樣佔據視窗空間。

若將display屬性設定為none，則不只會讓元件消失，而且也會將在視窗中佔據的空間釋放，藉以允許其他元件填補這個尚未被佔據的空間。注意看看圖13-12中的例子，在這個例中，由於第4個image的display屬性被設定成none，因此，正常來說本來要佔據的空位，就會被第5個image佔去了。若此屬性不設定為none，而設定成其他的屬性：block、inline或list-item，則會使得元件被顯示出來。在Internet Explorer 4中，block、inline和list-item這幾個設定值的效果是一樣的。但在Internet Explorer 5中，則元件會分別顯示成區塊元件(block element，即在元件之前會換行)、一個行內元件(in-line element，就像句子中的一個文字那樣放置)、或就像標準文字。未來的Internet Explorer版本，可能會對於list items會有進一步的支援。

控制部分顯示

您已經看到height和width屬性是如何控制元件在視窗上的大小。而overflow這個CSS屬性則是讓您決定，當元件某部分放不進所設定的height和width範圍之中時，該如何處理這種情況。程式13-13展示overflow屬性。而圖13-13則展示了Internet Explorer如何顯示此網頁。目前，Netscape Navigtor 4並不支援overflow屬性。19

<HTML>
<HEAD>
<TITLE>Listing 13-13</TITLE>
<STYLE>
  DIV {
    background: darkgray;
    width: 75;
    height: 75;
    margin: 10;
    float: left;
    }
</STYLE>
</HEAD>
<BODY>
A global style sheet sets the background color，height，width，
margin，and float for all DIV's. The float allows the DIV's to
display on the same line. Notice how wide lines (a series of
W's) are handled in each case.
<DIV>
  WWWWWWWW A standard DIV，with no additional styles specified.
  It expands beyond the height specified to hold all the text.
</DIV>
<DIV STYLE="overflow:visible">
  WWWWWWWW This DIV specifies an overflow of visible.
  It also expands beyond the height specified.
</DIV>
<DIV STYLE="overflow:hidden">
  WWWWWWWW This DIV specifies an overflow of hidden.
  This one is completely restricted to the specified size.
</DIV>
<DIV STYLE="overflow:scroll">
  WWWWWWWW This DIV specifies an overflow of scroll.
  Both scroll and both vertical and horizontal scrollbars appear.
</DIV>
<DIV STYLE="overflow:auto">
  WWWWWWWW This DIV specifies an overflow of auto.
  This means that scrollbars appear where needed.
</DIV>
<DIV STYLE="overflow:auto">
  This DIV specifies an overflow of auto.
  Without the W's，only a vertical scroll bar appears.
</DIV>
</BODY>
</HTML>
程式13-13

圖13-13　overflow屬性控制如何在網頁上顯示一個限制大小(constrained-size)的元件

圖13-13顯示了6個不同的DIV元件。在這個例子中，我們用了一個整頁樣式表，將所有DIV元件的高度與寬度設定為75 pixels，另外也設定了其他的屬性，包括float ，這個屬性我們將在本章稍後介紹。請注意，第一個DIV元件並沒有設定overflow屬性，請看看它會如何展開來，符合這段文字的高度與寬度。剩下的DIV元件則都設定了overflow屬性，其4個可能的屬性設定值為：visible、hidden、scroll和auto。第二個DIV元件將overflow設定為visible，這同時也是overflow的預設值，其與第一個DIV的運作方式相同。第三個DIV將overflow設定成hidden。這會使元件截掉不符合所設定長寬大小的部分。若將overflow設定為scroll，則元件旁邊會出現水平和垂直捲軸，不論文字內容是否需要捲軸，捲軸都仍會出現。最後，若將overflow屬性設定為auto，則捲軸只會在需要時才會出現。注意第5個DIV元件包含一個水平捲軸 (可以讓您捲動來看到一連串的W字元)與一個垂直捲軸 (可以讓您將文字內容向下捲動)。因為最後一個DIV元件將這一連串的W字元去除了，所有它只有垂直的捲動軸。若將overflow屬性設定成clip，則可以只讓元件的中間部分、右上部分或下半部顯示出來。程式列表13-14展示了clip屬性，而圖13-14顯示的是瀏覽結果。

<HTML>
<HEAD>
<TITLE>Listing 13-14</TITLE>
<STYLE>
IMG {position:absolute}
</STYLE>
</HEAD>
<BODY>
<IMG SRC="three.gif" STYLE="left: 0">
<IMG SRC="three.gif" STYLE="left: 40; clip: auto">
<IMG SRC="three.gif" STYLE="left: 80; clip: rect(0 20 20 0)">
<IMG SRC="three.gif" STYLE="left: 120; clip: rect(5 30 30 5)">
<IMG SRC="three.gif" STYLE="left: 160; clip: rect(5 20 auto 0)">
</BODY>
</HTML>
程式13-1420

圖13-14　clip屬性讓您將一個物件切割成特定的大小

使用clip屬性，就像在桌上出版軟體上所使用的圖形切割工具一樣。Clip可為物件指定一個要顯示的矩形區域，Clip有兩個可能值：auto和rect(top right bottom left)。其中，auto是預設值，可讓元件完整顯示出來。而rect設定則可以讓您指定4個值，以定義出元件要顯示出來的矩形範圍（接下來，都稱之為顯示視窗）。這四個設定值會指定元件顯示視窗之上下左右邊緣相對於元件本身之上邊緣及左邊緣的距離。舉例來說，第一個設定值設定的是元件其矩形顯示視窗的最上邊和元件上方邊緣的距離。例如，在圖13-14中的第三個IMG圖形元件，其rect的top部分的設定值為0，因此整個圖形的上面部分則都會被顯示出來。而第四個圖形的矩形顯示視窗，則是由元件的上緣及左緣處分別往下及往右設定5 pixels，並且將兩個設定值分別延伸到距離物件上緣和左緣的30 pixels處。任何這4個rect設定都可被設定成auto，因為auto可讓顯示視窗的邊緣自動延伸至物件的邊緣大小。不過為了使用這個屬性，元件必須先設定成絕對定位才行。請注意，clip屬性在Netscape 4或Opera 3.5瀏覽器中並不支援。

float和clear屬性

在程式13-13中,我們使用float屬性來讓DIV元件依照一行行相鄰放置，而非彼此疊置。float屬性是用來在文件中將元件偏離其原本的位置，然後讓其他元件圍繞著它。clear屬性則讓您指定哪裡不允許浮流元件存在。程式13-15展示了float和clear屬性的用法。而圖13-15則展示了使用Internet Explorer瀏覽這個網頁後的結果。

<HTML>
<HEAD>
<TITLE>Listing 13-15</TITLE>
<STYLE>
DIV {width: 100; background: darkgray}
</STYLE>
</HEAD>
<BODY>
<DIV STYLE="float: left">This DIV uses float left.</DIV>
<SPAN>
The DIV element has a value set for float.
Note how it floats on the side specified.
</SPAN>
<P>
<DIV STYLE="float: left">This DIV uses float left.</DIV>
<SPAN STYLE="clear: left">
In this SPAN，the clear CSS attribute has been set to left.
This means that it will not allow floating elements to its left.
</SPAN>
</BODY>
</HTML>
程式13-1521

圖13-15　float和clear屬性讓您控制物件周圍的浮流元件

圖13-15顯示兩個不同的SPAN元件。每個SPAN之前都有一個設定值為flaot的DIV元件。Float屬性可以設定為：left、right或none。當DIV元件的float屬性設定成None時，DIV元件會表現得好像沒有設定float屬性一樣。而當DIV元件設定了float:left屬性時，則此DIV元件將出現在SPAN元件的左邊。

Note

雖然很多HTML元件都支援float屬性，但是當float屬性使用在SPAN或DIV元件時，則必須為HTML元件指定width屬性。

在圖13-15中的第二個SPAN顯示了clear屬性的運作方式。這個SPAN元件的clear屬性設定成left，也就是不允許有其它元件浮流在它的左邊。基本上，clear屬性的允許設定值有：none、left、right和both。其中none為預設值，允許元件可以自由浮流。若設定both，則會使得元件的左右邊都不能有其它元件浮流。

我們目前所使用的CSS屬性，主要都是用來處理文字與其他標準的WEB元件。在下一章中，我們要看看如何使用CSS來控制其他瀏覽器特性。例如滑鼠指標、表格、條列清單、和列印。


實戰Dynamic HTML網站技術=>用CSS來控制其他瀏覽器元件

用CSS來控制其他瀏覽器元件
小
工
具 加入書架
加入書籤
上一章
下一章

除了目前我們談過的CSS屬性外，CSS還有許多其他可以用來控制非文字元件 (例如指標、列印控制、表格、和清單的屬性) 的屬性，在本章我們將來看看這些屬性。這些屬性大部分都還很新，有些仍在提案階段，也有些在舊的規格中被視為不重要的角色。因此，比起其它CSS屬性，比較沒有被廣泛支援。

利用CSS來控制表格

在CSS level-2規格中，border-collapse和table-layout是兩個新的表格屬性。這兩個屬性目前只有Internet Explorer 5支援， Internet Explorer 4和Netscape則並不支援。

border-collapse屬性1

比起從前，border-collapse CSS屬性提供了更好的表格邊框設定。這個屬性只有collapse和separate兩個設定值。separate值是預設值，其作用在於使表格以預設值顯示。程式14-1示範了這個屬性的使用方式，而在圖14-1中顯示的是瀏覽結果。

<HTML>
<HEAD>
<TITLE>Listing 14-1</TITLE>
</HEAD>
<BODY>

This is a standard table, with BORDER="1".
<TABLE BORDER="1">
  <TR>
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
  <TR>
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
</TABLE>
<P>

This is a standard table, with BORDER="1" and CELLSPACING="0".
<TABLE BORDER="1" CELLSPACING="0">
  <TR>
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
  <TR>
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
</TABLE>
<P>

This table also has BORDER="1", and has the CSS attribute
border-collapse set to collapse.
<TABLE STYLE="border-collapse:collapse" BORDER="1">
  <TR>
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
  <TR>
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式14-1

圖 14-1 使用 border-collapse 來瓦解邊框

在圖14-1的第一個表格是一個設定BORDER = "1" 的傳統表格。每個儲存格都有邊框，且還有一個繞在整個表格外面的邊框。儲存格彼此之間是分開的，而且其外框間的距離預設為2個像素 (pixels)。第二個表格的CELLSPACING屬性設為0，所以相鄰的儲存格邊界不允許有空隙。因為每個儲存格都有1 pixel厚的邊框，所以儲存格之間就會有2個像素 (pixels) 厚的間隔。在第三個表格中，border-collapse屬性被設定成collapse。利用此屬性，邊框與邊框本身的空間縮小了，每個儲存格與相鄰的儲存格之間，只剩下1 pixel厚的邊框。這種瓦解邊框的屬性，在其他類型的程式中也可以發現相近的特性，例如Microsoft Excel和Microsoft Access。

table-layout屬性2

table-layout CSS屬性是用來解決瀏覽器顯示表格時的效率問題。傳統的表格特性是它們會先了解表格的內容，舉例來說，如果表格內有一個儲存格的內容很長，那麼整個欄位下的內容都會擴展至最寬的寬度。所以有一個缺點就是在表格顯示前，整個表格要先被載入，才能確定最寬的儲存格的寬度。當table-layout是fixed固定時，您可以給表格中所有儲存格一個任意寬度。在處理大型表格時，這個特性可大大增加顯示效率。程式14-2示範了如何配合height和width屬性，來使用此屬性。

<HTML>
<HEAD>
<TITLE>Listing 14-2</TITLE>
</HEAD>
<BODY>
This is a standard table.
<TABLE BORDER="1">
  <COL WIDTH="50"><COL WIDTH="50"><COL WIDTH="200">
  <TR HEIGHT="20">
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
  <TR HEIGHT="20">
    <TD>Wider Column</TD><TD>Information</TD><TD>Information</TD>
  </TR>
</TABLE>
<P>
This is the same table, but with table-layout set to fixed.
<TABLE BORDER="1" STYLE="table-layout:fixed">
  <COL WIDTH="50"><COL WIDTH="50"><COL WIDTH="200">
  <TR HEIGHT="20">
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
  <TR HEIGHT="20">
    <TD>Wider Column</TD><TD>Information</TD><TD>Information</TD>
  </TR>
</TABLE>
<P>
This is the same table, with table-layout set to fixed and row
height removed.
<TABLE BORDER="1" STYLE="table-layout:fixed">
  <COL WIDTH="50"><COL WIDTH="50"><COL WIDTH="200">
  <TR>
    <TD>Information</TD><TD>Information</TD><TD>Information</TD>
  </TR>
  <TR>
    <TD>Wider Column</TD><TD>Information</TD><TD>Information</TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式14-2

圖14-2　使用設定為fixed的table-layout屬性來控制表格的配置

圖14-2顯示了3個表格，每個表格的資料都是相同的。第一個表格是一個傳統表格，它使用了COL元件將前兩欄的寬度設定為50 pixels，而第三欄設定為200 pixels。因為50 pixels的寬度不足以容納 "Information" 這個字，所以儲存格會擴展開來符合文字。在表格每列都有一個特定的高度，以容納一行文字。不過，因為第二列中有一個儲存格中有兩行文字，所以第一個表格的第二列的所有儲存格都垂直擴展一列的高度。

第二個表格加入一個設定為fixed的table-layout屬性。fixed值會強迫表格接受利用COL和TR元件所指定的寬度和高度，而不管儲存格的內容。任何超過儲存格寬度的文字，不是被隱藏，就是被截斷一部份；至於超過儲存格高度的內容則會被截斷。3

第三個表格跟第二個十分類似，除了沒有設定列的高度外，表示儲存格的內容只能在垂直方向擴展，而不能在水平方向擴展。

上面這個表格並不夠大，因此您可能會看不出任何在效率上的改善，但它的確示範了儲存格空間的絕對屬性。在隨書光碟中第14章的目錄中有一個LrgTable.htm，示範了兩個表格載入瀏覽器時，速度上顯著的不同。那兩個表格中，有一個使用table-layout設定成fixed ，另一個則沒有設定table-layout。

利用CSS來控制指標

指標CSS屬性可以讓您改變滑鼠指標的樣子，例如，只伸出一隻手指的手可以變成抓取狀的手、或者是變成箭頭。在很多情況下改變指標顯示的形狀十分有用。例如：若您想要預先提醒使用者，某個圖形是可以按鈕後執行的，您可以將滑鼠移至此圖形時，指標的樣式設定成手狀。程式14-3展示所有不同的cursor屬性設定。而圖14-3則顯示指標移到每個儲存格時，不同的指標樣式。

<HTML>
<HEAD>
<TITLE>Listing 14-3</TITLE>
</HEAD>
<BODY>
<TABLE BORDER="1" CELLSPACING="0" CELLPADDING="4">
  <TR HEIGHT="50" VALIGN="TOP">
    <TD STYLE="cursor:auto">auto</TD>
    <TD STYLE="cursor:hand">hand</TD>
    <TD STYLE="cursor:move">move</TD>
    <TD STYLE="cursor:text">text</TD>
    <TD STYLE="cursor:wait">wait</TD>
    <TD STYLE="cursor:help">help</TD>
    <TD STYLE="cursor:default">default</TD>
    <TD STYLE="cursor:crosshair">crosshair</TD>
  </TR>
</TABLE>
<BR>

<TABLE BORDER="1" CELLSPACING="0" CELLPADDING="4">
  <TR HEIGHT="50">
    <TD STYLE="cursor:w-resize">w-resize</TD>
    <TD STYLE="cursor:nw-resize">nw-resize</TD>
    <TD STYLE="cursor:n-resize">n-resize</TD>
    <TD STYLE="cursor:ne-resize">ne-resize</TD>
    <TD STYLE="cursor:e-resize">e-resize</TD>
    <TD STYLE="cursor:se-resize">se-resize</TD>
    <TD STYLE="cursor:s-resize">s-resize</TD>
    <TD STYLE="cursor:sw-resize">sw-resize</TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式14-3

4
圖14-3　指標CSS屬性控制滑鼠指標的顯示

16個指標屬性的可能值是auto、hand、move、text、wait、help、default、crosshair、w-resize、nw-resize、n-resize、ne-resize、se-resize、s-resize、和sw-resize。請參考圖14-3的內容。Netscape Navigator 4目前並不支援這個屬性。

使用CSS來控制列印

page-break-before和page-break-after CSS屬性並不會修改網頁在螢幕上的顯示，這兩個屬性是用來控制文件的列印方式。每個列印屬性都可以設定4種設定值：auto、always、left和right。其中Auto是預設值，只有在有需要時，才需設定分頁符號 (Page breaks)。page-break-before若設定成always，則是在遇到特定的元件時，印表機會重新開始一個新的列印頁。page-break-before若設定成left，則會插入分頁符號，直到指定的元件出現在一個左邊的空白頁上。page-break-before若設定成right，則會插入分頁符號，直到指定的元件出現在一個右邊的空白頁上。page-break-after屬性會將分頁符號加在指定元件後，而非之前。在程式14-4中您將可以看到這些屬性的設定，而圖14-4則是在螢幕上顯示這個網頁的結果。

<HTML>
<HEAD>
<TITLE>Listing 14-4</TITLE>
</HEAD>
<BODY>
<DIV>This is the first DIV.</DIV>
<DIV STYLE="page-break-before:always">This is the second DIV.</DIV>
<DIV STYLE="page-break-after:always">This is the third DIV.</DIV>
<DIV>This is the fourth DIV.</DIV>
<DIV STYLE="page-break-before:right">This is the fifth DIV.</DIV>
<DIV STYLE="page-break-after:right">This is the sixth DIV.</DIV>
<DIV>This is the last DIV.</DIV>
</BODY>
</HTML>
程式14-4

5
圖14-4 CSS屬性page-break-before和page-break-after會影響列表的結果，而不會直接顯示在網頁上

此程式列表會產生5頁的列印文件。第一頁只包含第1個DIV。第2個DIV的page-break-before屬性設定為always，所以分頁符號會插入DIV之前，而DIV元件會出現在第二頁。第3個DIV也是顯示在第二頁，因page-break-after設定成always，所以分頁符號會插入在此元件之後。在Internet Explorer 4中設定值為left和right時，列印文件會插入分頁符號。而Internet Explorer 5則會插入一或二個分頁符號，直到換到適當的左或右頁面。

Note

一些beta版本的Internet Explorer 5並不支援left和right設定值。至於Netscape Navigator 4則根本就不支援page-break屬性。

使用CSS來控制清單

CSS有許多屬性可以影響HTML清單的外觀。其中，list-style-type屬性讓您可從9種項目符號中挑選；list-style-image可以讓您使用圖形當作項目符號；而list-style-position屬性可以控制相對於項目符號的項目文字位置；至於，list-style則是一個綜合屬性，可以控制所有的list-style屬性。程式列表14-5使用了list-style-type屬性，且在下一頁的圖14-5顯示結果。

list-style-type CSS屬性與HTML屬性TYPE十分相似，不過卻更具彈性。list-style-type共可使用9個設定值：disc、circle、square、none、decimal、lower-roman、upper-roman、lower-alpha、和upper-alpha。前四個設定值讓您設定清單中每一個項目前面的符號形狀。剩餘的設定值是用來設定項目的順序。其中，decimal可以讓項目使用10進位數字來做排序；lower-roman可以讓項目使用小寫羅馬字母來做排序；而upper-roman則可以讓項目使用大寫羅馬字母來做排序。另外，lower-alpha或upper-alpha會使項目依據字母順序排序。不像HTML的TYPE屬性，在Internet Explorer中，這9個設定值中的任一個都可使用在有序 <OL> 和無序 <UL> 清單。Netscape Navigator 4支援部分的這類屬性﹔其可接受的設定值為：decimal、lower-roman、upper-roman、lower-alpha、和upper-alpha (這些是給有序清單用的)；另外還有disc、circle、square、及none (這些是給無序清單用的)。

<HTML>
<HEAD>
<TITLE>Listing 14-5</TITLE>
</HEAD>
<BODY>
<UL>
Each of the following LI tags has the CSS attribute
<I>list-style-type</I> set to the specified value.
  <LI STYLE="list-style-type:disc">disc
  <LI STYLE="list-style-type:circle">circle
  <LI STYLE="list-style-type:square">square
  <LI STYLE="list-style-type:none">none
  <LI STYLE="list-style-type:decimal">decimal
  <LI STYLE="list-style-type:lower-roman">lower-roman
  <LI STYLE="list-style-type:upper-roman">upper-roman
  <LI STYLE="list-style-type:lower-alpha">lower-alpha
  <LI STYLE="list-style-type:upper-alpha">upper-alpha
</UL>
</BODY>
</HTML>6
程式14-5

圖14-5　您可以透過list-style-type CSS屬性，來控制清單的項目符號

使用list-style-image這個CSS屬性，您也可以選擇使用自己喜歡的圖檔來當作項目符號。程式列表14-6使用這個屬性，而圖14-6顯示的則是其結果。

<HTML>
<HEAD>
<TITLE>Listing 14-6</TITLE>
</HEAD>
<BODY>
<UL>
The following LI tags have <I>list-style-image</I> specified.
  <LI STYLE="list-style-image:url(one.gif)">url(one.gif)
  <LI STYLE="list-style-image:url(img/two.gif)">url(img/two.gif)
  <LI STYLE="list-style-image:url(img/three.gif)">url(img/three.gif)
  <LI STYLE="list-style-image:none">none
</UL>

<HR>
<UL STYLE="list-style-position:outside">
  <LI>This demonstrates how setting a list-style-position
    of outside affects the way that text will wrap.
  <LI>This demonstrates how setting a list-style-position
    of outside affects the way that text will wrap.
</UL>

<UL STYLE="list-style-position:inside">
  <LI>This demonstrates how setting a list-style-position
    of inside affects the way that text will wrap.
  <LI>This demonstrates how setting a list-style-position
    of inside affects the way that text will wrap.
</UL>
</BODY>
</HTML>
程式14-6

7
圖 14-6 list-style-image屬性可將圖形設定為一個項目符號，而list-style-position 屬性則可控制文字環繞的位置

在程式列表14-6中包含4個項目。前三個項目使用list-style-image和相對的url來指向一個特定圖片。其中，第1個項目指向url (one.gif)，其圖形檔案名稱為one.gif ，放置在與lst14-6.htm相同的資料夾中。第2個項目指向url(img/two.gif)，其圖形檔案名稱為two.gif，放置在lst14-6.htm資料夾中的 img子資料夾中。list-style-image屬性也接受none設定值，也就是顯示預設的清單符號。目前，Netscape Navigator並不支援此屬性。

程式列表14-6同時也示範了list-style-postion屬性的使用方法， 它可以控制清單中文字如何相對於清單項目符號來做環繞。這個屬性的預設值為outside，它會使每一段文字的新行圍繞在項目符號右邊。在圖14-6中的最後一個清單項目示範了當list-style-position屬性設定為inside時的文字效果。這個位置會產生更複雜的項目清單，因為文字會繞到符號的下方。

講到這裡，我們已經學會如何使用動態樣式來設定靜態網頁了。在下一章中，我們將會深入探討在網頁顯示後，如何使用script來改變元件的樣式，讓樣式可以真的動起來。


實戰Dynamic HTML網站技術=>動態樣式腳本語言設計

動態樣式腳本語言設計
小
工
具 加入書架
加入書籤
上一章
下一章

在4.0或更新版本的Microsoft Internet Explorer中，動態樣式 (Dynamic Styles)能配合Script讓元件的格式可以隨時產生動態的變化。使用動態樣式，您的網頁將可以：

  • 隨使用者的輸入，改變網頁文字的大小、粗細、甚至字型樣式
  • 展開或隱藏大綱項目
  • 在螢幕上移動元件1

可惜的是，Netscape Navigator支援的動態樣式實作方式和Internet Explorer並不一樣，所以元件一旦顯示到螢幕上，可能就很困難或無法改變。為了考慮瀏覽器的相容性，本章範例的設計盡量都用很簡單的方式，因此在不支援動態樣式的瀏覽器內，即使有特別的DHTML功能不被支援，也不會出現錯誤訊息。

CSS和動態HTML物件模型

到目前為止，我們已經知道如何使用樣式表的CSS屬性和傳統的HTML。每個支援STYLE屬性的HTML元件，在Internet Explorer裡都可以當成是一個擁有樣式子物件的物件，所有CSS屬性都可以當成這些樣式子物件的一個屬性來用。本章中，我們將學習如何利用Script來操作一個物件的樣式，這跟我們在本書第二部份中，Script控制其他種類的物件一樣。

在撰寫Script時，您可以透過動態HTML物件模型中各CSS屬性 (attributes) 的對應物件屬性 (properties)，來存取其樣式屬性。有時候，CSS屬性和它相對的物件屬性在名稱上會有些微的差距，因為CSS慣用的連字號(hyphen)並不允許使用在物件模型中，因為有可能會不小心被當做負數符號。通常，您可以除去屬性名稱中的連字號，然後將原本接在連字號後面的字母變成大寫，這樣就可以將CSS屬性轉換成為物件模型中的對應的物件。舉例來說，CSS屬性background-image對應的物件就是backgroundImage；而page-break-before屬性對應的物件就是pageBreakBefore屬性。

一些CSS屬性在動態物件模型中有多種表示方法，例如您可以透過script使用backgroundPosition，backgroundPositionX，或backgroundPositionY屬性(後兩個允許更特殊的控制)，來影響background-position這個CSS屬性。表15-1列出所有的CSS屬性及它們在動態物件模型中的相對屬性。

表15-1　CSS屬性和對應的物件模型屬性
CSS屬性2 | 物件模型屬性
background | background
background-attachment | backgroundAttachment
background-color | backgroundColor3
background-image | backgroundImage
background-position | backgroundPosition backgroundPositionX backgroundPositionY
background-repeat4 | backgroundRepeat
behavior | behavior
border | border
border-bottom | borderBottom5
border-bottom-color | borderBottomColor
border-bottom-style | borderBottomStyle
border-bottom-Width | borderBottomWidth
border-collapse6 | borderCollapse
border-color | borderColor
border-left | borderLeft
border-left-color | borderLeftColor7
border-left-style | borderLeftStyle
border-left-width | borderLeftWidth
border-right | borderRight
border-right-color8 | borderRightColor
border-right-style | borderRightStyle
border-right-width | borderRightWidth
border-style | borderStyle9
border-top | borderTop
border-top-color | borderTopColor
border-top-style | borderTopStyle
border-top-width10 | borderTopWidth
border-width | borderWidth
clear | clear
clip | clip11
color | color
[no equivalent] | cssText
cursor | cursor
direction12 | direction
display | display
filter | filter
float | styleFloat13
font | font
font-family | fontFamily
font-size | fontSize
font-style14 | fontStyle
font-variant | fontVariant
font-weight | fontWeight
height | height15 posHeight pixelHeight
ime-mode | imeMode
layout-grid | layoutGrid
layout-grid-char16 | layoutGridChar
layout-grid-char-spacing | layoutGridCharSpacing
layout-grid-line | layoutGridLine
layout-grid-mode | layoutGridMode17
layout-grid-type | layoutGridType
left | left posLeft pixelLeft
letter-spacing18 | letterSpacing
line-height | lineHeight
list-style | listStyle
list-style-image | listStyleImage19
list-style-position | listStylePosition
list-style-type | listStyleType
margin | margin
margin-bottom20 | marginBottom
margin-left | marginLeft
margin-right | marginRight
margin-top | marginTop21
overflow | overflow
overflow-x | overflowX
overflow-y | overflowY
padding22 | padding
padding-bottom | paddingBottom
padding-left | paddingLeft
padding-right | paddingRight23
padding-top | paddingTop
page-break-after | pageBreakAfter
page-break-before | pageBreakBefore
position24 | position
ruby-align | rubyAlign
ruby-overhang | rubyOverhang
ruby-position | rubyPosition25
table-layout | tableLayout
text-align | textAlign
text-decoration | textDecoration textDecorationBlink26 textDecorationLineThrough textDecorationNone textDecorationOverline textDecorationUnderline
text-indent | textIndent
text-justify27 | textJustify
text-transform | textTransform
top | top posTop pixelTop28
vertical-align | verticalAlign
visibility | visibility
width | width posWidth29 pixelWidth
word-break | wordBreak
z-index | zIndex

當您讀取或設定(寫入)樣式物件的一個屬性時，應該會使用到點表示法，這個點可以用來表示物件項目在動態物件模型中的位置。下面有一個叫做MySpan的SPAN的標籤，它包含了一個將這個SPAN元件的顏色指定為blue的STYLE屬性。

<SPAN ID="MySpan" STYLE="color:blue">Hello!</SPAN>30

要存取動態物件模型中的此物件，您可以將MySpan物件的名稱接上style子物件，最後加上color屬性。其點表示法如下：

MySpan.style.color

使用如上的類似敘述，即可透過物件模型來讀取屬性的設定值。舉例來說，如果要將MySpan的style子物件之color屬性的設定值，指定給itsColor變數，可使用下列此行的script：

Itscolor=MySpan.style.color

基於初始HTML標籤中的設定，itsColor變數就會被設成blue。

MySpan.style.color="red"

當上面此行被執行後，文字的顏色就會改變。由於red這個詞彙在物件模型中並沒有定義，因此必須被括在引號中。不然，它會被視為一個未定義的變數名稱red，並產生錯誤。31

如果將紅色設定給另一個已經被定義的變數，那麼在使用該變數時，就不需加上引號。請參考下面的Script 敘述，在這段敘述中，MySpan元件的顏色會變成紅色：

MyVariable="red"
MySpan.style.color=myVariable

數值資料也不需要雙引號括在外面。在下面的例子中，程式碼會將MySpan的width屬性設定成50。

MySpan.style.width=50

使用Script來讀取及設定CSS屬性

我們來看一個相當基本的例子，這個例子示範了如何利用script來讀取及設定CSS屬性。程式列表15-1告訴您如何使用scripting來找到及改變一個物件目前的樣式設定值。圖15-1展示的是程式碼在Internet Explorer中的初始顯示結果。在圖15-2中，當您在文字上按一下，螢幕上將會出現一個警示對話窗。繼續按下確定鈕後，使用者會接著看到另一個如圖15-3的警示對話窗。圖15-4示範的則是按下第二個警示對話窗中的按鈕後的效果。這個例子在Netscape Navigator 4並不會發生任何動作 (雖然沒有錯誤訊息產生)，因為Navigator並不支援SPAN元件的onclick事件。

<HTML>
<HEAD>
<TITLE>Listing 15-1</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function changeIt(oClicked){
  oCS=oClicked.style
  alert("You clicked the element named "+oClicked.id+".")
  alert("It is "+oCS.fontWeight+". Click OK to change it.")
  if (oCS.fontWeight=='bold'){oCS.fontWeight='normal'}
  else {oCS.fontWeight='bold'}
}
//-->
</SCRIPT>
</HEAD>
<BODY>
<SPAN ID=MySpan STYLE="font-weight: bold; cursor: hand"
      onclick="changeIt(this)">
Click me!  Then click me again!
</SPAN>
</BODY>
</HTML>32
程式15-1

圖15-1　在MySpan元件被按下前之顯示畫面

圖15-2　第一個警示對話窗

圖15-3　第二個警示對話窗33

圖15-4　在文字粗細改變後的最後之顯示畫面

我們來看一下程式15-1所建立的網頁架構。被命名為MySpan的SPAN元件有兩個CSS設定，分別是：設定成值為bold的font-weight屬性，以設定值為hand的cursor屬性。因此元件的文字預設就是粗體，且當滑鼠指標移到元件上方時，滑鼠指標將改變成手狀。MySpan元件還有一個行內onclick事件的事件處理程式，當文字被按到時，changeIt函式就會被呼叫。關鍵字this被當成一個參數傳遞給changeIt函式，告訴函式是哪一個元件被按到。在這個例子中，關鍵字this指的就是MySpan物件本身。

ChangeIt函式包含例子的核心部分，由於我們將會多次用到被按鈕物件的樣式，因此將其設定給一個變數，以增加執行效率，也讓程式設計變得容易一些。下行程式會出現一個警告對話窗並顯示一個文字字串。此字串是由三個文字片段串接而成的，分別是：You clicked the element named這段文字、及被按鈕的物件的id屬性設定值、和一個句號字元(.)。這些文字連接在一起，並顯示在對話窗中，其結果就變成：You clicked the element named MySpan. 因此，我們利用讀取id屬性來決定被按鈕元件的名稱。

下一行展示的是屬性如何被讀取。每個動態物件模型都包含了一個style子物件，這個子物件支援了許多不同屬性，例如fontWeight和cursor。oCS.fontWeight敘述式可參考到名稱為oCS的物件之fontWeight屬性，它被定義為被按鈕項目之style子物件。因此當程式執行時，oCS.fontWeight會讀取被按鈕項目其目前的fontweight設定值。這一行接著會產生一個警示對話窗告訴您被按鈕項目的文字粗細程度。

接下來，函式會測試被按鈕項目的字形粗細程度。如果項目文字是粗體，函式會將fontweight屬性改為normal，將文字字體變成一般文字。若項目文字不是粗體，則將之設定成粗體。注意我們只使用點表示法，來指定屬性的設定值，以及我們想要設定的特殊設定值。

透過使用程式15-1的script，我們能夠提示使用者某元件目前的狀態，並且根據文字目前的狀態，來改變其字體粗細。接著我們來看看一些更進階的例子。34

建立可摺疊式大綱項目

網頁中的大綱項目是一個十分受歡迎的網頁瀏覽工具。程式列表15-2提供的是一個利用動態樣式建立的大綱項目，當使用者在不同的標題上按鈕時，大綱項目會隨之展開或摺疊。圖15-5顯示的是大綱一開始摺疊起來，只能看到section標題文字的樣子。而圖15-6顯示的則是當使用者按下section 2時，section 2展開來顯示chapter列表的樣子。在這種狀況下，使用者若再按一次Section 2，則大綱項目就會摺疊回原來的型態。

<HTML>
<HEAD>
<TITLE>Listing 15-2</TITLE>
<STYLE>
  SPAN    {font-size: 18pt; cursor: hand}
  .on     {display: on}
  A       {text-decoration: none}
  A:hover {color: red; text-decoration: underline}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
// Set bSupportsDHTML to true for Internet Explorer 4 or later
var bDoesDHTML = ( (navigator.userAgent.indexOf("MSIE") >= 0) &&
                   (navigator.appVersion.substring(0，1) >= 4) )

// Only hide menu items if browser supports DHTML
if(bDoesDHTML){document.write("<STYLE>.off{display:none}</STYLE>")}

function doSection(secNum){
  if (bDoesDHTML){
    //display the section if hidden; hide it if it is displayed
    if (secNum.className=="off"){secNum.className="on"}
    else{secNum.className="off"}
  }
}
//-->
</SCRIPT>
</HEAD>
<BODY>
<SPAN onclick="doSection(Sec1)"><B>Section 1</B></SPAN><BR>
  <DIV CLASS="off" ID="Sec1">
       <A HREF="generic.htm">Chapter 1</A><BR>
  </DIV>
<SPAN onclick="doSection(Sec2)"><B>Section 2</B></SPAN><BR>
  <DIV CLASS="off" ID="Sec2">
       <A HREF="generic.htm">Chapter 2</A><BR>
       <A HREF="generic.htm">Chapter 3</A><BR>
       <A HREF="generic.htm">Chapter 4</A><BR>
       <A HREF="generic.htm">Chapter 5</A><BR>
  </DIV>
<SPAN onclick="doSection(Sec3)"><B>Section 3</B></SPAN><BR>
  <DIV CLASS="off" ID="Sec3">
       <A HREF="generic.htm">Chapter 6</A><BR>
       <A HREF="generic.htm">Chapter 7</A><BR>
       <A HREF="generic.htm">Chapter 8</A><BR>
       <A HREF="generic.htm">Chapter 9</A><BR>
       <A HREF="generic.htm">Chapter 10</A><BR>
  </DIV>
</BODY>
</HTML>
程式15-2

圖15-5　一開始以摺疊型式的大綱

35
圖15-6　當在Section 2處按鈕，則大綱會展開
Note

相對於本書大部分的例子來說，程式15-2是比較複雜的。比起其它例子，這個例子的程式碼是最有可能被直接複製並使用到Web上的，所以在設計這個例子時，我們儘可能地小心，以確保程式可以在不同的瀏覽器上執行。這個例子在Internet Explorer 4或更新版本中將可以發揮完整功能，不過我們也很謹慎地設計程式在其它瀏覽器中執行的狀況。因此, 在Internet Explorer 3和Netscape Navigator所有目前有的版本，大綱項目在一開始瀏覽時就會被完全展開。請參考 第23章 ，取得對於跨瀏覽器網頁的深入探討。也請看 第24章 ，在該章將會介紹可展開功能選單的製作。

在程式15-2中的這段script程式有三個主要的部分。第一個部分測試瀏覽者所使用的瀏覽器是否為Internet Explorer 4或更新版本。如果是，則將bDoesDHTML變數設定為true。36

若bDoesDHTML是true，則下一段程式會在文件中加入一行程式碼。這行程式是一個STYLE元件，它會建立一個新的off類別。注意我們想要隱藏的大綱部份會使用到這個類別，但是只有對於使用Internet Explorer 4或更新版本的使用者，這些項目才會被隱藏起來，因為我們只針對這些使用者定義了off類別。

在script區段中的最後一段程式是doSection函式，它使用了display屬性來顯示或隱藏大綱項目的文字部分。每個section的標題都有一個onclick事件的處理程式。當使用者按下某個section時，doSection函式就會被呼叫，然後傳遞想要顯示或隱藏的元件名稱。若項目的類別是off的話，它會被改變成on，且會將項目元件顯示出來。若它本來就是on了(或其他任何情況)，它就會被改變成off，將元件隱藏起來。

當一個元件的display屬性被設定成none時，此元件就會被隱藏起來，且網頁也不會為這個元件配置空間。類似display屬性的visibility屬性也可以用來隱藏元件，不過元件的屬性設成hidden時，元件雖被隱藏了，但事實上在網頁上仍會為元件保留一個放置空間。程式15-3展示的是當您使用visibilty屬性，而非display屬性來隱藏項目時，會有什麼情況發生。在圖15-7中，您可以看到Internet Explorer一開始是如何顯示大綱項目時的，在一開始時，只有出現section的標題。請注意，網頁配置只允許顯示section內容 (就是Chapter的列表) 所需預留的空間。圖15-8展示的是在Section 2上按鈕的效果；即在Section 2後面所預留的空間中，顯示Chapter的列表。若您再按一次Section 2 ，則chapter的列表又會消失，不過預留的空間還是會保留。

<HTML>
<HEAD>
<TITLE>Listing 15-3</TITLE>
<STYLE>
  SPAN    {font-size: 18pt; cursor: hand}
  .on     {visibility: on}
  A       {text-decoration: none}
  A:hover {color: red; text-decoration: underline}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
// Set bSupportsDHTML to true for Internet Explorer 4 or later
var bDoesDHTML = ( (navigator.userAgent.indexOf("MSIE") >= 0) &&
                   (navigator.appVersion.substring(0，1) >= 4) )

// Only hide menu items if browser supports DHTML
if(bDoesDHTML){document.write("<STYLE>.off{visibility:hidden}</STYLE>")}

function doSection(secNum){
  if (bDoesDHTML){
    //display the section if hidden; hide it if it is displayed
    if (secNum.className=="off"){secNum.className="on"}
    else{secNum.className="off"}
  }
}
//-->
</SCRIPT>
</HEAD>
<BODY>
<SPAN onclick="doSection(Sec1)"><B>Section 1</B></SPAN><BR>
  <DIV CLASS="off" ID="Sec1">
       <A HREF="generic.htm">Chapter 1</A><BR>
  </DIV>
<SPAN onclick="doSection(Sec2)"><B>Section 2</B></SPAN><BR>
  <DIV CLASS="off" ID="Sec2">
       <A HREF="generic.htm">Chapter 2</A><BR>
       <A HREF="generic.htm">Chapter 3</A><BR>
       <A HREF="generic.htm">Chapter 4</A><BR>
       <A HREF="generic.htm">Chapter 5</A><BR>
  </DIV>
<SPAN onclick="doSection(Sec3)"><B>Section 3</B></SPAN><BR>
  <DIV CLASS="off" ID="Sec3">
       <A HREF="generic.htm">Chapter 6</A><BR>
       <A HREF="generic.htm">Chapter 7</A><BR>
       <A HREF="generic.htm">Chapter 8</A><BR>
       <A HREF="generic.htm">Chapter 9</A><BR>
       <A HREF="generic.htm">Chapter 10</A><BR>
  </DIV>
</BODY>
</HTML>
程式列表15-3

圖15-7　一開始使用visiblity屬性的大綱項目37

圖15-8　當在Section 2處按鈕，則大綱項目內容會動態地顯示在預留的空間
Note

程式列表15-2和15-3也展示了另外兩個有用的CSS應用。針對SPAN元件來設定cursor的CSS屬性為hand ，則當滑鼠指標的位置移動到section標題的上方時，會使得滑鼠指標改變成手狀指標。除此此外，注意A的text-decoration屬性設定為none，且A:hover被設定為紅色(red) 和底線(underlined)。這意味著所有的鏈結元件預設不會顯示底線，除非滑鼠指標從上面移動過去時，才會顯示紅色文字及底線。

在螢幕上產生移動效果

動態樣式可以讓您精確地設定物件在螢幕上的位置。透過改變可設定位置的一些屬性，讓物件可以產生移動效果，如程式15-4所示，圖15-9則展示了程式一開始在Internet Explorer視窗的顯示結果。在螢幕上移動滑鼠會使得SPAN元件繞著網頁移動，圖15-10只顯示其中一個可能的狀態 (本程式中在網頁中的動態移動效果，很難在此處清楚地展示，因此，您可以在書附光碟中執行chap15\lst15-4.htm來實際觀察這個動態效果)。

<HTML>
<HEAD>
<TITLE>Listing 15-4</TITLE>
<STYLE>SPAN {position:absolute}</STYLE>
<SCRIPT LANGUAGE="JavaScript">
function moveSpans(){
  Span1.style.top=15
  Span2.style.posTop=Span2.style.posTop+1
  Span3.style.left=10
  Span4.style.top=window.event.y
  Span5.style.posLeft=window.event.x
  Span6.style.pixelTop=window.event.x
  Span6.style.posLeft=window.event.y
}
</SCRIPT>
</HEAD>
<BODY onmousemove="moveSpans()">
<SPAN ID="Span1" STYLE="top: 0; left: 0">First Span</SPAN>
<SPAN ID="Span2" STYLE="top: 50; left: 50">Second Span</SPAN>
<SPAN ID="Span3" STYLE="top: 100; left: 100">Third Span</SPAN>
<SPAN ID="Span4" STYLE="top: 150; left: 150">Fourth Span</SPAN>
<SPAN ID="Span5" STYLE="top: 200; left: 200">Fifth Span</SPAN>
<SPAN ID="Span6" STYLE="top: 250; left: 250">Sixth Span</SPAN>
</BODY>
</HTML>
程式15-438

圖15-9　使用者移動滑鼠之前的網頁

圖15-10　使用者移動滑鼠之後可能出現狀況

程式15-4展示了改變用來控制元件位置的屬性的效果。所有在網頁中的SPAN元件的position屬性都設為absoulte，這樣可以讓我們由它們的起始位置設定精確的像素數 (pixel) 位置。要設定這些位置，我們使用top和left屬性。

NOTE

您可以使用許多不同的屬性來設定位置，例如top、posTop、pixelTop、left、和posleft。每個屬性有其特定情況下的用處，您可以在SBN Workshop網站或書附光碟中找到這些屬性的完整說明文件。在光碟中，其目錄層次是Workshop (References);DHTML，HTML & CSS;CSS，然後是CSS Attributes References。想要取得線上版本的說明，請連至MSDN線上資源網站 msdn.microsoft.com/resources/schumandhtml.htm39 ，或開啟書附光碟中的MSDN_OL.htm，然後選擇CSS Attribute References。

在程式15-4中的BODY元件有一個onmouseover事件的處理程式，只要滑鼠移動到Body區域，或者也可以想成，滑鼠在網頁中移動時，它就會呼叫MoveSpans函式。這個函式指定了當滑鼠移動時，每個SPAN元件的位置該如何改變。其中，Span1會垂直移動到離視窗頂端15 pixels的位置，然後停留在該位置上。當滑鼠移動時，Span2會固定下降1 pixel的位置 (因為只要滑鼠在任何一個方向移動一個pixel，它的posTop的設定值就會被增加1) 。Span3會水平移動到距離視窗左邊界10 pixels的位置，然後停留在該處 (若要回復視窗的初始狀態，可按F5重新整理一下)。因為Netscape Navigator 4並不支援BODY元件的onmouseover事件處理程式，所以在Netscape瀏覽此網頁時，它永遠不會呼叫moveSpans函式，所以也不會改變元件在視窗上的位置。

接下來的三個SPAN元件會改變它們相對於滑鼠的位置。window.event.x和window.event.y屬性會指出滑鼠目前的位置。當滑鼠垂直移動時，Span4也會垂直移動；滑鼠若水平移動，則Span5也會跟著水平移動。至於Span6則是在滑鼠水平移動時，產生垂直移動；而當滑鼠垂直移動時，產生水平移動；如此當滑鼠繞著圓形移動時，就會產生有趣的移動效果了。

如何使用動態樣式來建立視窗中移動位置的例子，可在SBN Workshop網站或在書附光碟中workshop\author\dhtml\tutorial\asteroids.htm找到。這個例子的程式碼大概有600行，這個例子只用了動態樣式、scripts、和一些圖像，即做出一個古老的小行星射擊遊戲(Asteroids) 。玩玩看喔！相信您在玩過後，一定會有非常深刻的印象的！

正如您在前幾章所看到的，動態樣式可以讓您透過改變一些慣用的CSS屬性的方式，改變元件的文字顏色到元件的位置等特性。下一章將介紹如何使用其它方式，建立有多媒體與動畫的網頁。

實戰Dynamic HTML網站技術 視窗縮放
動態樣式腳本語言設計


實戰Dynamic HTML網站技術=>視覺特效濾鏡以及轉換特效

視覺特效濾鏡以及轉換特效
小
工
具 加入書架
加入書籤
上一章
下一章

視覺特效濾鏡以及轉換特效，可以在文字、圖片、及其他物件上加上特殊的視覺效果。由於特效部分瀏覽器會作處理，所以可以節省圖形下載的時間。在Microsoft Internet Explorer 4.0及以後的版本中，可透過CSS的filter屬性使用這些濾鏡。目前濾鏡功能並沒有放在W3C的CSS規格中，而且Internet Explorer是唯一一個支援濾鏡特效的瀏覽器。本章將介紹如何使用濾鏡及轉換的特效，以及如何將他們融入網頁使用的技巧。

概論

適當的使用濾鏡特效，可以大幅改變網頁元件的外觀。舉例來說，濾鏡可以將圖片或一個文字區塊，沿著水平軸垂直翻轉。或是在圖形或文字上，加上指定方向的漸層或是陰影效果。而轉換特效，可以處理元件在轉換狀態時的特殊效果。這種特效和看電視的淡入淡出，以及左右變換處理畫面的方式，非常相近。

經由CSS濾鏡 (filter) 屬性，可設定使用濾鏡及轉換特效。利用樣式來控制濾鏡以及轉換特效，比起使用特殊的Script、ActiveX控制項、或是Java applets來得方便。除了讓程式設計工作可以變得更簡單外，還可以提供向下相容的能力，讓不了解CSS及濾鏡的屬性的瀏覽器，也能正常顯示網頁。因為任何不了解CSS的瀏覽器，會自動忽略這些標籤﹔即使瀏覽器不能在元件上套用濾鏡，但依然可以正常顯示網頁內容，不會造成當機或是傳回錯誤。而我們在DHTML的行為 (Behaviors) 處理上，依舊會使用這種技巧。我們會在本書的第五部份中，介紹此種技巧。1

下面的工具可以幫助你建立濾鏡及轉換特效，這些工具所放的位置在指定的光碟目錄下。

工具 | 在書附光碟中的位置
Filter Wizard | /Workshop/sample/author/dhtml/filtwizard/filtwzrd.htm
Wave Filter Wizard | /Workshop/sample/author/dhtml/wavewizard/wavewzrd.htm2
Transitions Wizard | /Workshop/sample/author/dhtml/overview/trnswzrd.htm

你可以在Microsoft.com/workshop目錄下，找到SBN Workshop工具的線上版本。

濾鏡

filter濾鏡可以提供14種視覺效果，下表中列出了它們的名稱以及功能。

濾鏡 | 效果3
Alpha | 設定物件的透光度及透明度
Blur | 建立有方向性的模糊效果，建立物件移動的感覺
DropShadow | 建立一個物件複製品，然後指定一個方向的位移，製作出陰影的效果
FilpH4 | 製作物件的水平鏡射影像
FilpV | 製作物件的垂直鏡射影像
Glow | 在物件周圍加上光影的模糊效果
Grayscale | 將物件的色彩資料轉換為灰階方式顯示5
Invert | 將物件的輝度、飽和度及亮度資料反相，建立相片負片式的效果
Light | 製作在物件上打光的效果
Mask | 利用物件建立一個透明遮罩
Shadow6 | 做出物件的輪廓向後加上位移，建立出陰影的特效
Wave | 在物件上加上波浪效果
X-ray | 僅顯示物件的外框

濾鏡的使用方式和其他的樣式一樣，可以經由STYLE屬性、全域的樣式表 (global style sheet)、或是連結樣式表 (linked style sheet) 來設定。而filter濾鏡屬性的設定，是透過filter屬性後加上濾鏡名稱，以及放在括弧中所需的引數來完成程式碼16-1中，顯示了如何在 <DIV> 標籤中加上Blur濾鏡，進而改變其中文字的外觀，而圖16-1則顯示了修改的結果。

<HTML>
<HEAD>
<TITLE>Listing 16-1</TITLE>
<STYLE>
  DIV {width: 100%;font: 32pt Arial bold}
</STYLE>
</HEAD>
<BODY>
<DIV STYLE="filter: blur(add=1, direction=135, strength=5)">
This DIV has the blur filter applied.
</DIV>
<DIV>
This DIV does not.
</DIV>
</BODY>
</HTML>7
程式16-1

圖16-1　在物件上加入模糊濾鏡
會加以解釋)、將字體設定為大型字、格式為粗體、字型為Arial。然後濾鏡 (filter) 被以行內格式，套用在文字內。此時我們利用了三個引數，分別是：add、direction、strength。add引數決定了原始的字串是否要出現在陰影前，或是只要顯示陰影就

在程式碼6-1中的樣式表中，設定了物件的寬度 (在下節好了。程式碼16-1中的add數值設定為1，代表原始的字串要被加到陰影上。若該數值設為0，則原始的文字將會從陰影上移除。direction引數設定了模糊 (blur) 的方向，它是根據物件垂直軸順時針方向方向計算。這個參數是以每45度作為計算單位，可出現的數值包括0 (向上)、45 (右上)、90 (右)、135 (右下)、180 (下)、225 (左下)、270 (預設值，左)、315 (左上)。而strength數字設定了以點數 (pixels) 為基準的模糊長度。大部分的濾鏡都有多個不同的引數 (有時被視為參數)，但有些濾鏡一個都沒有。完整的參數討論在SBN Workshop網站上，你可開啟書附光碟的Workshop (Reference) 檔案，依照順序選擇：DHTML、HTML&CSS﹔CSS﹔CSS Attributes Reference﹔Filter﹔然後參考與Visual Filter有關的內容。或參考msdn的線上資訊 msdn.Microsoft.com/resources/schurmandhtml.htm ﹔最後還有一個方法，就是從書附光碟的MSDN_OL.htm檔案中，選擇Visual Filter項目。8

視覺特效濾鏡只能用在下列HTML元件上：BODY、BUTTON、DIV、IMG、INPUT、MARQUEE、SPAN、TABLE、TD、TEXTAREA、TFOOT、TH、THEAD及TR。DIV及SPAN則要先設定height或width等CSS屬性，或是CSS的position屬性設定為absolute。

程式碼列表16-2使用了一些濾鏡作示範，圖16-2則顯示圖片套用濾鏡的結果。

<HTML>
<HEAD>
<TITLE>Listing 16-2</TITLE>
</HEAD>
<BODY>
<IMG SRC="car.gif">
This image uses no filters.<BR>
<IMG SRC="car.gif"
     STYLE="filter:alpha(opacity=70, finishopacity=0, style=1)">
    This image uses the alpha filter.<BR>
<IMG SRC="car.gif"
     STYLE="filter:flipv">
This image uses the flipv filter.<BR>
<IMG SRC="car.gif"
     STYLE="filter:glow(color=blue)">
This image uses the glow filter.<BR>
<IMG SRC="car.gif"
     STYLE="filter:chroma(color=red)">
This image uses the chroma filter.<BR>
<IMG SRC="car.gif"
     STYLE="filter:wave(strength=6, freq=4, lightstrength=25)">
This image uses the wave filter.<BR>
</BODY>
</HTML>
程式16-2

在程式碼16-2中，使用的是IMG標籤而不是DIV，而圖片是一張去背過的GIF圖檔。我們使用了alpha、flipv、glow、chroma、以及wave濾鏡。有一些濾鏡可以設額外的參數，但是此處我們並沒有用到。舉例來說，alpha透明度濾鏡就可以設定透明度opacity及透明度結束finishopacity點的位置。

圖16-2　其他可使用的濾鏡9

經由Script使用濾鏡的方法

先前我們使用filter濾鏡，都是利用行內嵌入 (in-line) 的方式。但是濾鏡也可以經由物件模型，讓script直接呼叫使用。每個元件都有style子物件，而style其下又有filter物件。因此一個濾鏡的值可以這樣設定：

object.style.filter = "glow(color=red)"

程式16-3是一個如何利用事件來設定樣式的範例，圖16-3則是顯示的結果。

<HTML>
<HEAD>
<TITLE>Listing 16-3</TITLE>
<STYLE>
  DIV {width:100}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
function addFilt(oWhich){
  oWhich.style.filter="glow(color=red, strength=2)"
}
function removeFilt(oWhich){
  oWhich.style.filter=" "
}
</SCRIPT>
</HEAD>
<BODY>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
</BODY>
</HTML>
程式16-3

10
圖16-3　經由script動態套用樣式

當頁面載入時，文字還不會立刻套上樣式。當滑鼠的指標移到任何一個DIV元件上時，addFilt函式會自動將樣式套用到相對的物件上。當指標移到元件外時，removeFilt函式就會發生作用。這個範例簡單的示範了如何利用一些小技巧，就可以在網頁中加入互動效果。你可以在一個物件上，同時加上許多不同的濾鏡，以製作出更複雜的網頁。程式16-4示範了如何在文字上套用glow及wave濾鏡，圖16-4就是結果。

<HTML>
<HEAD>
<TITLE>Listing 16-4</TITLE>
<STYLE>
  DIV {width:250;font-size:36}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
function addFilt(oWhich){
  oWhich.style.filter="glow(color=red, strength=5); wave(freq=3,
        lightstrength=50, phase=0, strength=2)"
}
function removeFilt(oWhich){
  oWhich.style.filter=" ";
}
</SCRIPT>
</HEAD>
<BODY>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
<DIV onmouseover="addFilt(this)" onmouseout="removeFilt(this)">
Mouse over me!
</DIV>
</BODY>
</HTML>
程式16-4

程式碼16-4是將程式碼16-3稍作修改而來的，在全域的樣式設定中，我們已經將字型稍微調大一些，方便檢視變化的結果。wave濾鏡的名稱及引數，在此被加到與glow濾鏡同一行的doFilt函式中。注意在不同的濾鏡間，被加上了一個分號及空格。若沒有這樣做，只有第一個濾鏡可以正常運作。因為我們更改了doFilt敘述，所以當使用者將游標移到文字上時，兩個特效將會同時作用。你可以將更多的濾鏡套用到同一個物件上，但是要注意圖16-4也顯示了過多的特效，對內容可讀性的影響。

圖16-4　在一個物件上套用多個濾鏡11

注意一點，雖然程式碼16-4有關濾鏡的敘述，在本書上被列印成兩行，但是你應該把它輸入成一行。另一種將濾鏡加到一個script的方法，就是將濾鏡依序加到敘述中。舉例來說，若要將glow、filpv、chroma濾鏡加到同一個敘述中，你可以使用下列的敘述方式：

oWhich.style.filter = ("glow(color=red, strength=5); " +
                      "flipv(); " +
                      "chroma (color=black)")

現在我們利用這些濾鏡搭配上一些小變化，程式碼16-5是一個滑鼠指標移到文字上時，隨機套上glow以及wave濾鏡的示範。若指標一直停留在文字上，則wave濾鏡的phase引數就會隨著時間改變。當指標離開文字後，濾鏡就會隨之恢復原狀。

<HTML>
<HEAD>
<TITLE>Listing 16-5</TITLE>
<STYLE>
  DIV {width: 250; font-size: 24pt; font-weight: bold;}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
var count=0; var thePhase=0; var aniOn=0;
var colorList=new Array("red", "blue", "green");

//this function changes the wave filter phase
function anitext(){
  thePhase=(thePhase + 10)
  MyDiv.filters[0].phase=thePhase
  // the next line causes this function to be called 5 times/second
 oTO=window.setTimeout("anitext()",0200,"JavaScript")
}

function doFilt(){
  MyDiv.style.filter="wave(add=0, freq=3, lightstrength=50, phase=0,
strength=2, enabled=1); "
  rndNum=Math.floor(Math.random() * 3)
  MyDiv.style.filter+="glow(color=" + colorList[rndNum] + ", strength=5)"
  anitext()
}

function removeFilt(){
  window.clearTimeout(oTO)
  MyDiv.style.filter=" "}
</SCRIPT>
</HEAD>
<BODY>
<DIV ID="MyDiv" onmouseover="doFilt()" onmouseout="removeFilt()">
Demonstration of dynamic filters
</DIV>
</BODY>
</HTML>
程式16-5

在程式碼16-5中，我們使用了一些新的技巧。在處理當指標移到文字上的doFilt函式中，會產生一個0到3的隨機數值。它被用來從取出一個顏色，供glow濾鏡使用。然後第2個anitext被呼叫用來以遞增10的方式設定引數phase的值，然後設定一個計時器以便重新呼叫這個函數。在200 ms之後 (1/5秒)，wave濾鏡的phase就繼續變化，直到滑鼠指標移開時為止。此時DIV的onmouseout會呼叫removeFilt函式。除了將原先套用在文字上的效果移除外，也停止了計時器的計時功能，停止文字上的效果變化。

這些技巧顯示了濾鏡的一部份變化，接下來我們要介紹轉換特效 (transition)，利用轉換特效，你可以在網頁中加入更多的互動效果。12

轉換特效

濾鏡可以讓目前在螢幕上的物件，擁有不同的顯示外觀。轉換特效可以控制物件出現在瀏覽器上的方式，或是從瀏覽器移除的方式。Internet Explorer支援兩種不同的轉換特效：一種就是漸變轉換 (blend)，另一種則是直接變換式的轉換。漸變轉換是利用淡入淡出的方式，來顯示物件。因為它的變化方式比較簡單，所以通常只需要一個引數：延遲時間 (duration)，它定義了效果變化的週期時間長度。而直接變換式的轉換可以從多種變換樣式中，選取一種套用在轉換的物件上。表16-1列出了變換效果名稱及代碼。

表16-1　轉換特效以及相對的數值
轉換特效 | 相對數值 | 轉換特效 | 相對數值13
外框以矩形方式向內縮小 | 0 | 隨機的畫面融合效果 | 12
外框以矩形方式向外放大 | 1 | 由兩側垂直向內顯示14 | 13
外框以圓形方式向內縮小 | 2 | 由中心向外顯示 | 14
外框以圓形方式向外縮小 | 315 | 由上下垂直向內顯示 | 15
由下至上顯示圖片 | 4 | 由中心水平向外展開 | 16
由下至上顯示圖片16 | 5 | 由右上到左下展開 | 17
由左至右顯示圖片 | 6 | 由右下到左上展開 | 1817
由右至左顯示圖片 | 7 | 由左上到右下展開 | 19
垂直百葉條紋轉換 | 8 | 由左下到右上展開18 | 20
水平百葉條紋轉換 | 9 | 隨機水平條紋填滿顯示 | 21
水平方塊式轉換 | 1019 | 隨機垂直條紋填滿顯示 | 22
垂直方塊式轉換 | 11 | 隨機選取一種顯示 | 23

程式碼16-6是利用隨機的畫面融合方式顯示圖片，圖16-5是圖片轉換中的樣子。20

<HTML>
<HEAD>
<TITLE>Listing 16-6</TITLE>
<SCRIPT FOR="window" EVENT="onload" LANGUAGE="JavaScript">
  flower.filters.item(0).apply()
  flower.style.visibility="visible"
  flower.filters.item(0).play()
</SCRIPT>
</HEAD>
<BODY>
<!--
  transition 12 is "random dissolve"
  Change transition value for different effects
-->
<IMG ID="flower" SRC="flower.gif";
     STYLE="visibility: hidden;
            filter: revealtrans(duration=2.0, transition=12)">
</BODY>
</HTML>
程式16-6

圖16-5　圖片的每一個部分，會慢慢的顯示出來

在程式碼16-6的 <IMG> 標籤中，我們先將圖片設成不可見的狀態 (就是將visibility屬性設為hidden)，然後讓它在稍後顯示出來。請注意轉換特效在 <IMG> 標籤中，被當成STYLE濾鏡屬性處理。duration引數設定了轉換特效所花的時間，而transition引數設定了要使用哪種轉換特效 (在前面的列表中，我們可以找到每個轉換特效的數值)。

當頁面被載入時，在 <HEAD> 標籤區域內的script執行，並且在影像物件上執行了3項工作。而這些程式碼，就是你了解轉換特效的關鍵。轉換特效再使用時，一定要使用一些狀態變化控制。在此例中，圖片起始時是處於看不到的狀態。在Script的第一行中，套用了我們在 <IMG> 標籤中所定義的濾鏡。在此時它並不是真的執行轉換特效，因為我們還沒指定目標的狀態。目標的狀態在下一行中做了設定，我們希望可以看到圖片。最後一行呼叫play() 方法時，才真正的套用了轉換特效，讓影像能夠淡入到瀏覽器中。

程式碼16-7讓你能以按下按鈕的方式，實際體驗24個效果的變化結果。圖16-6顯示了其中一個轉換特效的結果。21

<HTML>
<HEAD>
<TITLE>Listing 16-7</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var curVal=0;
//put all the names of the reveal transitions in an array
var tNames=new Array("Box In", "Box Out", "Circle In",
      "Circle Out", "Wipe Up", "Wipe Down", "Wipe Right",
      "Wipe Left", "Vertical Blinds", "Horizontal Blinds",
      "Checkerboard Across", "Checkerboard Down",
      "Random Dissolve", "Split Vertical In", "Split Vertical Out",
      "Split Horizontal In", "Split Horizontal Out",
      "Strips Left Down", "Strips Left Up", "Strips Right Down",
      "Strips Right Up", "Random Bars Horizontal",
      "Random Bars Vertical", "Random");

function nextFilter(){
  ff=flower.filters.item(0)
  if (ff.status!=2) {
    flower.style.visibility="hidden"
    ff.transition=curVal
    ff.apply()
    flower.style.visibility="visible"
    ff.play()

    window.status="Transition " + (curVal) + " " + tNames[curVal]
    nextBtn.value=("Next Transition is " + tNames[curVal+1])

    if (curVal==23){curVal=0}
    else{curVal=curVal + 1}
  }
}
</SCRIPT>
</HEAD>
<BODY>
<IMG ID="flower" SRC="flower.gif";
     STYLE="visibility: visible;
            filter: revealtrans(duration=2.0, transition=1)">
<P>
<INPUT TYPE=button ID=nextBtn onclick="nextFilter()"
       VALUE="Next Transition is Box In">
</BODY>
</HTML>
程式16-7

圖16-6　套用在花上的轉換特效

每當按鈕被按下時，就會呼叫nextFilter函式。這個函式會先檢查目前的轉換狀態，以確定沒有其他的濾鏡正在作用。如果沒有其他濾鏡作用，就先將圖片的狀態設成是看不見的隱藏狀態。然後轉換特效設定成變數curVal的值，接著套用在影像上。轉換特效值curVar每次執行時都會加1，當超過23時就恢復為0。而目前使用的轉換特效利用window.status敘述寫入狀態列，然後下一個轉換特效的名稱就會被寫到按鈕上。

將特效結合

轉換特效以及濾鏡特效可以加以組合，做出更多奇異獨特的效果。要將不同的特殊效果結合起來其實很簡單，只要將他們當成是filter的引數寫入STYLE的屬性中即可，程式碼16-8就是結果。在圖16-7中，你可以看到當陰影濾鏡，加上融合及圓形轉換特效時，所展現的特殊效果。22

<HTML>
<HEAD>
<TITLE>Listing 16-8</TITLE>
<SCRIPT FOR=window EVENT=onload LANGUAGE="JavaScript">
  car.filters.item(0).apply()
  car.filters.item(1).apply()
  car.style.visibility="visible"
  car.filters.item(0).play()
  car.filters.item(1).play()
</SCRIPT>
</HEAD>
<BODY>
<IMG ID="car" SRC="car.gif"; STYLE="visibility: hidden;
     filter: revealtrans(duration=2.0, transition=12)
             revealtrans(duration=2.0, transition=3)
             shadow(color=gray, direction=135)">
</BODY>
</HTML>
程式16-8

圖16-7　在陰影濾鏡上套用融合及圓形轉換特效的結果

在程式碼16-8中，我們使用了兩個轉換效果以及一個濾鏡。注意每一個轉換效果，都要使用獨立的apply以及play敘述。同時你也可以利用在script的play方法中，加入其它數值作為取代duration的引數使用。舉例來說，要將圓形變換的時間從2秒變成4秒，只要將最後一行script程式碼改成car.filter.item(1).play(4) 就可以了。

頁面轉換的效果

前面的例子都在強調如何使用在元件上，套用轉換的效果。Internet Explorer同時也提供你一個方法，讓你能夠在網頁的頁面轉換期間，套用這些轉換效果。當你在進入或離開網頁時，都可以套用這些轉換效果。23

頁面轉換的效果可在網頁的 <META> 標籤中完成設定，在下例中我們可以直接看到成果。要看到轉換的效果，我們必須使用兩個網頁。一個就是原始網頁，另一個則是變換後的網頁。程式碼16-9中包含了一個簡單的圖形以及超連結，黃色的底色讓您能將變換看得更清楚。

<HTML>
<HEAD>
<TITLE>Listing 16-9</TITLE>
</HEAD>
<BODY BGCOLOR="yellow">
<A HREF="lst16-10.htm">Click here for an interpage transition</A>
<P>
<IMG SRC="magic.gif">
</BODY>
</HTML>
程式16-9

在程式碼16-9的超連結中，我們指定了一個連結到目標網頁的超連結。目標網頁在此也是以非常簡單的模式設計，裡面只有一張圖片。目標網頁的程式碼在16-10中﹔而你可以看到如圖16-8的轉換成果。

<HTML>
<HEAD>
<TITLE>Listing 16-10</TITLE>
<META HTTP-EQUIV="Page-Enter"
      CONTENT="revealtrans(duration=3.0, transition=23)">
<META HTTP-EQUIV="Page-Exit"
      CONTENT="revealtrans(duration=3.0, transition=23)">
</HEAD>
<BODY>
<A HREF="lst16-9.htm">Click here for an interpage transition</A>
<P>
<IMG SRC="flower.gif">
</BODY>
</HTML>
程式16-10

24
圖16-8　頁面轉換的特效

注意程式碼16-10中包含了兩個 <META> 標籤，它控制了轉換的詳細方式。第一個指定了觸發變化的事件 (在此是page-enter事件)、轉換的時間、以及轉換所使用的效果 (使用編號23的隨機選取轉換的效果)。要看轉換的成果，只要打開程式碼16-9 (書附光碟chap16下的lst16-10.htm檔案)，然後按下超連結連結到目標頁。在程式碼16-10的第2個 <META> 標籤中，經由設定HTTP-EQUIV的方式，來控制頁面離開的效果。

視覺濾鏡以及變換效果可以在不增加太多頻寬需求條件下，展現特殊的網頁效果。在下一章中，我們將討論如何利用高頻寬及低頻寬，在網頁上加入多媒體及特殊效果。


實戰Dynamic HTML網站技術=>網頁上的多媒體效果

網頁上的多媒體效果
小
工
具 加入書架
加入書籤
上一章
下一章

一個 "多媒體" (multimedia) 的網頁，可能包括有會動的圖片及對應的背景音樂，或是需要高頻寬的視訊效果。因為多媒體的範圍是如此的廣泛，所以有許多的工具或方法能製作出多媒體的效果。而現在的瀏覽器，也多具備了許多不同種類多媒體的播放能力。本章包括了一些多媒體的概論，也討論到不同瀏覽器間的多媒體製作。同時也介紹一些製作多媒體網頁的方法，方便你製作出多采多姿的多媒體網頁。

概論

一般來說，多媒體網頁是利用一些技巧，讓使用者能夠得到視聽感官上的最大滿足。一些常見的多媒體技巧包括有：

  • 動態的標誌。1
  • 一個新聞網站是用動態的視訊傳送新聞，而不是一般的文字。
  • 電影公司在網站上公佈預告片段的影片檔。
  • 網路唱片行在網頁上提供音樂的試聽服務 (.mp3)。
  • 在個人網頁上加入所喜愛的背景音樂。
  • 電腦訓練中心利用多媒體製作互動性的線上教材。

利用多媒體效果來設計網頁的同時，能讓使用者瀏覽起來依舊保持流暢是很有挑戰性的一件工作。當你在網頁上大量使用多媒體時，同時會消耗掉大量的網路頻寬，因此可能對播放多媒體檔案造成困難。下面讓我們來簡單看一看，幾種主要的多媒體型式。

聲音及影像2

聲音及影像是網頁上最早出現的兩種多媒體型式，它們可以直接在瀏覽器中播放，也可以獨立出來在另一個視窗中播放。在傳送這些龐大的檔案時，有許多不同的方式可供選擇。其中包括了全部下載後再播放檔案，或是在下載的同時播放聲音及影像 (也就是我們所熟知的流動式 (streaming) 播放)。本章將介紹如何在網頁上，加入聲音及影像供不同的瀏覽器使用。而 第18章 將會更深入的討論，媒體控制項的使用方式。

媒體控制項

在Internet Explorer 4之後，提供了一個DirectAnimation Multimedia控制項來解決有關多媒體傳送時發生的頻寬問題。這些控制項 (只有Internet Explorer支援) 讓網頁設計者只要告訴瀏覽器怎樣顯示控制項物件的方式，來減少檔案傳送的體積。在某些情況下，的確可以解決許多頻寬所造成的問題。舉例來說，一個擁有旋轉物件的影片檔，可能會很大。但是若利用DirectAnimation Multimedia控制項來製作相同的效果，可能需要的檔案體積及資料就小得多。Internet Explorer提供了4個DirectAnimation Multimedia控制項：

  • Structured Graphics控制項是用來建立簡單的向量圖形，並提供了縮放及3度空間旋轉的能力。
  • Sequencer控制項用來控制事件的流程及發生時機。3
  • Path控制項決定物件的放置點以及移動路徑。
  • Sprite控制項可以在頁面加入其它額外的影像，同時可以控制播放的張數及方式。

請參考 第19章 相關的說明。

其他種類的多媒體效果

瀏覽器通常可以播放多種的媒體檔案，包括有Macromedia的Flash以及Shockwave、虛擬實境標記語言 (Virtual Reality Markup Language，VRML)、Math ML.. 等等，因為這些特殊的格式需要協力廠商的編輯程式才能進行編輯工作，所以我們在此將不會做進一步的討論。4

Macromedia Flash是一種常見的多媒體工具，它除了可以做出簡單包含聲音的動態按鈕外，還可利用做出包含聲音、影像、以及各式線條所組成的圖片。因為它的檔案資料都是向量格式，所以檔案通常都很小。要播放Flash的檔案需要Flash專屬的播放程式 (Internet Explorer 4.0以後的版本，以及許多不同的瀏覽器都擁有免費的Flash播放程式可以使用。製作Flash的檔案則需要Macromedia的特殊編輯程式。Flash相關的資料可在Macromedia的網站Macromedia.com上。

ChromeEffects是Internet Explorer 5或是Microsoft Windows 98以及Windows 2000使用者，能使用的新式高品質多媒體特效。舉一個簡單的例子來說，ChromeEffects在一個旋轉的方塊上，可以在每面放上不同的影像以及網頁。由於這種使用此技術的使用者不多，所以在本書中我們也不加討論。

播放多媒體

瀏覽器播放多媒體的傳統方法，是利用協力廠商的外掛程式 (plug-ins) 來播放聲音及影像。但隨著瀏覽器技術的成熟，許多外掛式的多媒體播放程式與瀏覽器間都發生了相容性的問題。因市面上擁有許多不同的瀏覽器廠牌及版本，所以要多媒體檔案之間保持良好的相容性也是很困難的。

EMBED標籤

在網頁上加入聲音最常用的方式就是 <EMBED> 標籤。若你要加入影像檔案，<EMBED> 標籤一樣可以做到。在目前大部分的瀏覽器中 (Internet Explorer 3以後)，都支援這個標籤。程式碼17-1簡單的示範了如何利用 <EMBED> 標籤，將聲音加入網頁中。圖17-1則顯示了Internet Explorer中的媒體控制項﹔而圖17-2則顯示了在Netscape Navigator中的媒體控制項外觀。

<HTML>
<HEAD>
<TITLE>Listing 17-1</TITLE>
</HEAD>
<BODY>
<EMBED SRC="music.wav"
       VOLUME="50"
       HEIGHT="60"
       WIDTH="145"
       AUTOSTART="true"
       ALIGN="left"
       HIDDEN="false"
       LOOP="true">
</EMBED>
</BODY>
</HTML>5
程式17-1

圖17-1　Internet Explorer中的聲音控制項

圖17-2　在Netscape Navigator 4中的情形

注意在Netscape及Internet Explorer中顯示的控制項外觀並不一樣，不過兩個瀏覽器不是只有兩個控制項的外觀不同而已。每個瀏覽器還支援一些彼此之間互不相容的功能選項，或是不同的預設值。表17-1就是這些不同屬性的列表。

表17-1　在Internet Explorer與Netscape Navigator的 <EMBED> 標籤屬性預設值及功能列表6
屬性 | 屬性及預設值說明
ALIGN | 功能和 <IMG> 標籤下的ALIGN功能相同
AUTOSTART | 只有true或是false值，決定是否要自動播放指定的媒體。而預設值根據HIDDEN狀態值，以及電腦平台而有所不同 (Macintosh或PC)，所以你最好明確指定這個屬性的值。
ENDTIME7 | 以分：秒 (mm:ss) 的格式指定媒體播放的停止時間，只有Navigator可以使用。
HEIGHT | 指定控制項的點像素高，如果沒有指定這個數值的話，Navigator可能會發生意料之外的情況。
HIDDEN | 指定true或是false值，決定控制項是否要出現在螢幕上。當要在頁面上加入背景音樂時，最好把值設為true。
HREF | 讓控制項與指定的URL位址連結，僅在Internet Explorer中適用。8
LOOP | true或是false，Navigator還支援一個數值，而這個數值的功能和Internet Explorer的PLAYCOUNT一樣
NAME | 給予控制項一個名稱
PLAYCOUNT | 指定媒體檔案的播放次數，只有Internet Explorer支援
PLUGINSPACE9 | 指定哪裡有外掛程式可供播放媒體。若你只是需要播放WAV或是MID之類的媒體檔案，不需要加此說明。
PLUGINURL | 指定哪裡可以找到PLUGINSPACE中指定必須安裝的軟體。只有Navigator支援。
SRC | 要播放的媒體檔案位置
STARTTIME | 以分：秒 (mm:ss) 的格式指定媒體播放的開始時間，只有Navigator可以使用10
TARGET | 和 <A> 標籤的TARGET標籤類似，只有當HREF設定時，才有作用。同時也只有Explorer支援
VOLUME | 設定音樂音量的大小，只有Navigator支援。當此值設為50時，與Internet Explorer播放的音量相等
WIDTH | 指定控制項的點像素寬，如果沒有指定這個數值的話，Navigator可能會發生意料之外的情況。

程式碼列表17-1中在網頁中加入了一個音效檔。只要將SRC指向的檔案變成影像檔，就可將內嵌的聲音變成影像。程式碼17-2是修改的示範，結果顯示在圖17-3及圖17-4中。11

<HTML>
<HEAD>
<TITLE>Listing 17-2</TITLE>
</HEAD>
<BODY>
<EMBED SRC="clouds.avi"
       VOLUME="50"
       HEIGHT="286"
       WIDTH="320"
       AUTOSTART="true"
       ALIGN="left"
       HIDDEN="false"
       LOOP="true">
</EMBED>
</BODY>
</HTML>
程式17-2

圖17-3　在Internet Explorer中的影像控制項

圖17-4　影像開始後，同樣內容在Netscape中播放的結果

當Netscape Navigator第一次載入頁面時，你可能會注意到它提示您要雙按視窗下方，以便啟動內嵌的圖片。按照指示動作後，結果就會如圖17-4。在Internet Explorer中，聲音的控制面板和影像的控制面板是相同的。但是在Netscape中，情形就不一樣了。在Netscape 3中需要額外的外掛程式，才能播放視訊檔。若使用者未安裝所需的外掛程式，則螢幕上會出現提示自Netscape指定的下載地點下載。12

在Internet Explorer中，<EMBED> 標籤可用來啟動Microsoft媒體控制項 (或被稱為Microsoft Active Movie控制項)，它可以提供Internet Explorer各式各樣的媒體播放能力。媒體控制項可以利用script來做到進一步的控制，我們將在下一章一併做討論。

在新視窗中播放媒體

<EMBED> 標籤可用來將聲音或影像加入網頁。但是若想要讓這些聲音及影像在新視窗中開啟，則有許多種方法。下面是其中的兩種：

利用錨 <A> 標籤開啟媒體

當錨標籤 (Anchor) 的HREF屬性指向一個媒體檔案時，按下此超連結時，系統自動會啟動預設的媒體播放程式。程式碼17-3是一個簡單的示範。當Cloud超連結被按下時，Netscape Navigator會啟動Windows的媒體播放程式。它會開啟一個新的視窗播放媒體影像檔，結果在圖17-5中 (若系統設定不同，可能預設開啟的媒體播放程式亦不同)。

<HTML>
<HEAD>
<TITLE>Listing 17-3</TITLE>
</HEAD>
<BODY>
<A HREF="clouds.avi">Click here to launch the Clouds video.</A>
</BODY>
</HTML>
程式17-313

圖17-5　在瀏覽器外播放媒體影像

你可以注意到Windows媒體播放程式的外觀，和Internet Explorer中 <EMBED> 標籤所使用的控制項類似。這是因為不論在使用 <EMBED> 標籤、或是Script來控制媒體、或是直接播放一般的媒體檔案，Windows都使用相同的媒體播放程式元件。它們之間的不同僅在於呼叫這個元件的方式而已 (在Windows 98中，可利用開始功能表下的：程式集/附屬應用程式/視聽娛樂的分類目錄下，找到Windows Media Player)。

利用Script的window.location來播放媒體

第2個方法和使用 <A> 標籤相當類似，就是將window物件的location屬性指向媒體檔案，程式碼17-4就示範了此種技巧。

<HTML>
<HEAD>
<TITLE>Listing 17-4</TITLE>
</HEAD>
<BODY>
<FORM>
<INPUT TYPE="button" VALUE="Click here to launch the Clouds video"
       onclick="window.location='clouds.avi'">
</FORM>
</BODY>
</HTML>
程式17-414

這個方法所製作出的外部播放媒體效果和程式碼17-3相同。在此例中，我們選擇使用表單中的按鈕，來觸發播放媒體影像檔。因為Netscape Navigator或是Internet Explorer都支援INPUT的TYPE="button" 的按鈕，所以我們使用此種辦法來啟動簡單的script。

串流式播放媒體

有許多種的資訊處理方式可讓使用者在下載資料的同時，同時播放多媒體檔案。現在有兩種普遍的方法：一種就是利用Microsoft NetShow播放程式 (也就是Windows媒體播放程式)，另一種則是RealNetworks的RealPlayer。Netscape Navigator以及Internet Explorer在各種不同的電腦系統平台上，都可以播放NetShow、RealAudio、RealVideo等媒體檔案。

你可以在 http://www.real.com/ 網站上，找到更多有關建立此類多媒體檔案的資訊。而NetShow的資訊則可以在 microsoftcom/windows/windowsmedia15 及書附光碟的SBN Workshop中找到。請開啟光碟中的Workshop (Reference) 檔案下的﹔Streaming & Interactive Media﹔Windows Media Technologies。而線上版本的位置在 msdn.Microsoft.com/resource/schurmandhtml.htm ，您也可以開啟光碟中MSDN_OL.htm的Streaming & Interactive Media。

NetShow可以將聲音、影像及其他多媒體的資料以串流方式播放。它是由包含媒體的ASF (Active Streaming Format) 檔案格式，及包含說明資訊的ASX檔所組成。ASX檔中內含說明ASF檔播放方式、及提供主要伺服器忙碌或停止服務時，次要伺服器所在位置資訊。你可以從 microsoft.com/ntserver/basics/netshowservices 的位址，下載免費的工具將目前的影像及聲音檔案，轉換成ASF檔案格式。那裡提供了文字和圖形介面的檔案轉換工具、ASF檔案編輯工具、以及增益集 (add-ons) 和外掛程式 (plug-ins)。如此就可將Adobe Premiere及PowerPoint的檔案，轉換成NetShow使用的ASF格式。

Note

NetShow及ActiveMovie本身代表不同的技術，但是經過時間已經逐漸融合在一起。目前Windows大部分的多媒體檔案 (包括以前分別由NetShow以及ActiveMovie所處理的檔案)，Windows Media Player都可以處理。而支援檔案的副檔名包括：.avi，.asx，.rmi，.wav，.ra，.ram，.rm，.rmm，.mpg，.m1v，.mp2，.mpa，.mpe，.mid，.rmi，.qt，.aif，.aifc，.aiff，.mov，.au及 .snd。16

NetShow有一個優點，就是它可以將非多媒體的元件嵌入串流檔案中 (包括標準的Script程式碼，文字及其他特殊命令)，這個技術可被用來：

  • 在影像最後加入結束標題。
  • 建立一個多框架的網頁，其中一個框架中的NetShow串流資料，控制了其他框架資料來源的URLs位址。利用這個技術，我們可以將畫面切成一邊播放簡報資料，同時另一邊播放的是它的現場演說資料。
  • 在串流媒體資料中暗藏包含超連結的錨點，當每次NetShow視窗被按下時，連結到不同的Web位址。
  • 在串流媒體資料中暗藏包含超連結的錨點，當在不同時間NetShow視窗被按下時，連結的Web位址也不相同。

雖然你可將Windows Media Player內嵌到你的網頁中，不過通常我們會利用錨點，開啟一個新視窗來播放多媒體資訊。這個方法本章前面已經簡單介紹過了。程式17-5是將NetShow內嵌到網頁中，及利用錨點來開啟新視窗播放檔案的例子。

<HTML>
<HEAD>
<TITLE>Listing 17-5</TITLE>
<script language="JavaScript">
// This code makes Netscape Navigator better able to use the player.
if ( navigator.appName == "Netscape" ){
  navigator.plugins.refresh()
  document.write("\x3C" + "applet MAYSCRIPT
    Code=NPDS.npDSEvtObsProxy.class" )
  document.writeln(" width=5 height=5 name=appObs\x3E \x3C/applet\x3E")
}
</script>
</HEAD>
<BODY>
Embedded Media Player <BR>
<!-- Object tag is used by Internet Explorer -->
<OBJECT ID="MPlayer" width=160 height=112 type="application/x-oleobject"
     CLASSID="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95""
CODEBASR="http://activex.microsoft.com/activex/controls/
    mplayer/en/nsmp2inf.cab#Version=5,1,52,701"
     STANDBY="Loading Media Player components...">
  <PARAM NAME="FileName" VALUE="keister.asx">
  <PARAM NAME="AutoStart" VALUE="true">
  <PARAM NAME="ShowControls" VALUE="false">
  <!--Embedded plug-in for Netscape -->
  <EMBED TYPE="video/x-ms-asf-plugin" WIDTH="160" HEIGHT="112"
PLUGINSPAGE="http://www.microsoft.com/windows/mediaplayer/
    download/default.asp"
     FILENAME="keister.asx"
     SRC="keister.asx"
     CONTROLTYPE=0>
  </EMBED>
</OBJECT>
<P>
<A HREF="keister.asx">Start the Media Player in an external window.</A>
<P>
<A HREF="http://www.microsoft.com/windows/mediaplayer/download/">
Get the full version of the Media Player.</A>
</BODY>
</HTML>17
程式17-5

圖17-6　在網頁內播放媒體，以及開啟新視窗播放媒體的範例

程式碼17-5中內嵌了一個影像以及兩個超連結。這個簡單的多媒體檔案是來自於NetShow的網站，並針對28.8 k數據機連線所設計的。若使用者沒有下載Media Player，則會自動開啟使用者的Internet Explorer下載媒體播放程式。這是因為我們在HTML中，設定了ODEBASE屬性。在Netscape Navigator中若沒有這個媒體播放程式，會出現一個小圖示代表需要下載這個軟體。當按下這個圖示時，Netscape便會從PLUGINSPACE屬性的設定位址，下載播放程式。

Note

在網頁中在某些情況下，並不適合使用CODEBASE敘述。因為它可能只會下載一個簡單版 (light) 的播放程式，而不是下載完整的播放程式，所以可能會發生有些媒體格式將無法辨認及播放。此外當CODEBASE敘述指定下載32位元的Windows時版本時 (Windows 98、Windows NT、Windows 95)，Macintosh、Windows 3.X、或是UNIX系統的使用者將無法使用下載的程式 (雖然這些平台上有對應的軟體版本)。所以只有當你所有的客戶端都使用NetShow時，我們建議你在網頁中加入Windows Media Player超連結。不然你也可以使用我們在 23章 介紹的瀏覽器偵測技術，來偵測使用者的平台並使用正確的CODEBASE敘述。18

動態GIF檔

動態GIF圖形檔案是網頁上最常見的一種多媒體檔案格式，而且幾乎所有目前的瀏覽器都支援。動態GIF圖檔中，可以包含許多張不同的影像，並像電影一樣依序放出。程式碼17-6展示了如何在網頁中使用動態GIF檔案。

<HTML>
<HEAD>
<TITLE>Listing 17-6</TITLE>
</HEAD>
<BODY>
<IMG SRC="airplane.gif"><BR>
This page demonstrates an animated GIF.
</BODY>
</HTML>
程式17-6

圖17-7　動態GIF圖案的其中一格畫面

注意在HTML中，動或不動的GIF圖檔設定都一樣。只要一個 <IMG> 標籤加上SRC屬性就可以了。當SRC指向動態GIF圖檔時，GIF圖檔就會自己會動了。airplane.gif是Microsoft GIF Animator的一個範本檔案。而製作動態GIF，需要下列的一些工具：19

產品 | 何處取得 | 附記
Alchemy Mind Works GIF Construction Set | www.mindworkshop.com/alchemy/alchemy.html | 非常有力並可對細節作進一步的控制
Microsoft GIF Animator20 | 是Microsoft FrontPage以及Image Composer的一部份附屬工具。1.0版可在某些共享軟體的網站上找到。相關資訊請查閱 Microsoft.com/imagecomposer/gifanimator/gifanin.htm | 使用簡單，使用色盤方便
Right to Left Software Anamagic GIF | rtlsoft.com | 對圖檔作縮小最佳化的效能優異
GIFBuilder21 | 許多個人網站或是搜尋引擎都可找到 | 非常常用的Macintosh工具
WWW Gif Animator | 分享軟體站台 | 擁有非常高的評價，介面和Internet Explorer類似
Note

因為網路環境會隨著時間一直變化，所以當你讀到本書時，這些網站位址可能會有所改變。但你可到許多不錯的分享軟體以及免費軟體的網站試試看，例如： www.hotfiles.com22 ， http://www.shareware.com/ ， http://www.jumbo.com/ ， http://www.tucows.com/ ，以及23 wuarchive.wustl.edu.

這些工具常還可以建立擺放在其他物件上的透明GIF圖檔，而許多其他的設計工具，則可將成品輸出成動態GIF檔 (如Macromedia Flash)。

如何規劃多媒體網頁

在Web上加入多媒體其實有些訣竅。如果你不事先作良好的規劃，作出來的網頁通常都會過大導致下載時間太長、效果不佳、或根本不能執行。

頻寬

我們前面已經提到客戶端的頻寬是網頁設計的首要考量，對多媒體網頁來說尤其重要。通常聲音或影像檔案都很大，不事先計劃作出來的網頁通常都會過大。

雖然現在使用者上網的管道很多，但是大部分的人還是使用低速的撥接連線上網。不過高速上網的方式也越來越普遍，企業內部也多變已經擁有高速網路，甚至CD-ROM目前也逐漸變成常見的網頁資料來源了。24

當使用者是在透過Internet取得資訊，而你的多媒體資料卻是從CD-ROM或是企業內部的區域網路所提供時，你應該更加仔細考慮頻寬的限制。大部分的家庭用戶仍然使用28.8 k的數據機來存取Internet。換句話說他們每秒最多接收28800 bits的資料到瀏覽器中 (若考慮切割封包及其他檢查位元所浪費的傳輸頻寬，實際使用可能每秒只有20 kbps)。但是一台雙倍速的光碟機 (算是目前最慢的標準)，每秒都能傳輸600 KBytes的資料，這數據幾乎是數據機的200倍。而一般企業內的網路每秒可傳遞10 M bits的資料 (每秒大於1MB)，大約是數據機的400倍。有些企業內部甚至有100 megabits或是Gigabit (1000+ megabit) 以上的網路連線速度。撥接Internet也逐漸朝向高速網路邁進，例如ADSL (Asymmetric Digital Subscriber Line，非對稱式數位用戶線路) 提供256 kps到6Mbps以上的速度，有線電視寬頻網路甚至可提供30Mbps以上的速度。在此連線速度下，每秒可從硬碟中傳送5到50 megabits以上的資料到Internet上。

因為上網的速度差異如此的大 (幾乎是幾何倍數的差異)，所以相對的存取大量的多媒體檔案時，流暢度也會有明顯的差異，所以設計時要以一般的客戶端來作設計。如果你的大部分客戶是使用28.8 k的數據機連線，那麼即使有些客戶使用的是高速連線，你的網頁的大小還是需要作適當的控制。另一種解決的方式是提供不同幾析度的媒體檔案，依照使用者的頻寬來決定播放的檔案。

調色盤

調色盤就是指某些顏色的組合。大部分的多媒體以及圖片都使用了特定的色盤的顏色。少用一些顏色可以減少圖檔的體積，並且讓系統比較不好的電腦，也能正常顯示畫面的效果。當製作GIF檔時，常會遇到選擇調色盤的問題。因為製作GIF檔，一定需要選擇調色盤。一般最安全的調色盤，就是專為Web設計的調色盤 (Web-safe palette)。它是一個8位元的色盤，也就說它可以有256個顏色。不過實際上，色盤中只有216種顏色。其他40種顏色中，保留給作業系統20個顏色﹔剩餘20個則保留給使用者加入非安全色盤的顏色。在 \chap17\iesafe.pal以及 \chap17\iesafe.act有Windows PAL及Adobe Photoshop ACT格式的安全色盤。你可以在Web上找到許多安全調色盤，它們的顏色排列可能不同，不過包含的顏色應該是一樣的。

有一些影像檔也會使用到調色盤，同時某些影像檔可用特定調色盤來改善播放的效果。但大部分的影像檔，還是會使用在Web上不會出問題的顏色。實際使用的色盤是依照編碼及播放程式 (codec) 來決定，本章稍後會有編碼的相關說明。

Note

在圖片上使用正確調色盤的方法，每個繪圖軟體都不一樣，所以你必須參考繪圖軟體的說明文件。不過一般來說，都需要轉換色彩的使用數量 (有些軟體是用模式mode來表示)，也就是選擇調整24、8、32位元...等的調色盤設定。

最適合使用的工具25

Internet Explorer提供了許多媒體元件供你使用，但是因為選擇太多了，有時反而很難決定哪一種才是最好的方式。舉例來說，若我們想在網頁上加入動態影像，可以選擇動態GIF檔、影像檔、一個幾何圖案組合的圖形、MacroMedia Flash圖片。在你真正下手作出所需的媒體檔案前，還是得先考慮你的實際需要是什麼。接下來我們可以看個例子，了解如何選擇所使用的媒體元件。

舉例來說，我們現在需要占半頁版面在3 D空間內旋轉的2 D影像，影像中也不需要加入聲音。網頁的存取對象是28.8 k的撥接連線某公司外地售貨員，他們使用Internet Explorer作為瀏覽器。

根據這個預設的情況，我們可以分析各項方案的優缺點：

  • 可以使用動態的GIF檔，不過你可能需要將所有動畫製作完成後，放入另一個框架中。因為它需要佔掉網頁一半的畫面，所以GIF檔可能會很大。
  • 即使你把每一秒鐘的影片張數減少，佔半個畫面的影像檔還是會很大。當你需要將影音及影像結合時，使用影像檔可能是最好的方法，不過在此例中我們並不需要在影像中加入聲音。
  • 若使用圖案物件 (Structured Graphics) 製作圖案，製作出來後就可以利用Script讓物件作旋轉的工作。這種幾何圖形物件檔通常都很小，不會因為螢幕的大小及解析度影響圖檔的大小。同時這種檔案下載的時間，也會比其他的方式來得快。
  • Internet Explorer 4及以後的版本，都支援讀取Flash格式檔案的能力。同時大部分的瀏覽器，也都可以讀取Flash格式的檔案 (不過通常需要下載Flash的播放程式)。Flash的檔案和幾和圖形組成向量圖檔類似，檔案大小都不大，也不會隨著畫面大小改變。Flash唯一的缺點，就是製作Flash的檔案的工具需要另外購買。26

根據製作容易度、檔案下載時間、以及只需考慮Internet Explorer的用戶等分析的結果，使用圖案物件可能是比較好的選擇。如果預設條件改變的話，可能結果就會不相同。舉例來說，如果使用者擁有較高的頻寬，可能就可以使用影像檔案。如果客戶端使用Netscape Navigator，可以考慮使用Flash來製作檔案。

當製作多媒體檔案時，應該隨時注意下列事項：

  • 網頁上面同時有多少多媒體影像，一般來說，網頁上的媒體影像越多 (即使每個多媒體檔案都很小)，使用者使用網頁的效能就越低。造成的原因不僅是因為傳輸頻寬，而是因為多媒體檔案也十分耗損系統效能。
  • 考慮可使用的工具有哪些，舉例來說：要製作Flash檔案，就必須要使用Macromedia的Flash製作程式。若要將聲音及影像結合，就需要使用Adobe Premiere之類的影像剪輯程式。
  • 請考慮網頁上需要使用的顏色數量，低階使用者的電腦可能只能顯示256色。為了滿足各種使用者不同的需要，你可以製作許多不同規格的圖片。舉例來說，可以利用某個特定顏色的階層變化，來減少使用的顏色。不過最好先在256色的顏色模式下，測試網頁的效果 (8-bit顏色模式)。要調整螢幕顯示的顏色數量，在Windows 95、Windows 98、Windows NT上可以調整控制台的顯示器設定。在Macintosh的電腦上，可以調整控制台的螢幕設定。
  • 是否要對每個媒體的元件作控制。在Internet Explorer中你可以對每一個網頁元件作控制，所以在考慮解決方案前，應該分析你需要對多媒體檔案的控制是哪些。

建立網頁使用的聲音及影像檔27

建立在網頁上使用的高品質聲音及影像檔，是一件非常有挑戰性的任務。通常你需要協力廠商提供的軟體，以及相關的知識才能製作出所需的多媒體檔案。本節將討論製作媒體檔案時，一些基本的概念。但是不會說明太多有關專屬工具的使用和技巧。

建立影像檔

建立影像檔有許多的方式，你可以去買一張影像捕捉卡，將攝影機或是錄影帶的畫面加進電腦中。一些電視調頻轉換卡配合適當軟體，也可以將電視畫面抓到電腦中，或甚至購買一些裡面已經有影像的CD光碟。一旦影像載入電腦後，你就可以利用像是Adobe Premiere之類的工具，修改或是與其他的影像混合。或是進一步加上聲音及其他特效，更可以利用影像編輯程式直接以手繪方式建立影像檔案。

數位影像的都是由一張張的畫面組合而成的，傳統的動畫是利用軟片在鏡頭前面移動以製作出連續畫面的效果，通常播放的張數是每秒24張。電腦的影像檔案，也是根據此原理在運作。影像播放程式也會依照預設的順序，播放所有的影像。不過在電腦上，程式開發人員可以對影像作進一步的設定，例如影像播放的每秒畫面數...等。

影像檔案的大小

影像檔案算是Web上常見的大檔案，一分鐘長的影片就跟一本小說文字檔一樣大。影響影像檔大小的因素有很多，例如：編碼方式、影像大小、播放速率、顏色多寡、聲音品質等...都會影響影像檔的效率。

編碼方式28 當影像檔在電腦上製作和播放時，分別要經過壓縮以及解壓縮的程序。因為一張24 bit、640 X 480大小的影像大約需要900 KB，每秒播放15張播放30秒的影片，大約就需要405 MB (大需是800本10萬字的小說)。所以電腦每秒需要播放13.5 MB的影像，遠超過一般電腦所能負擔的程度，更不要說是一般數據機的傳輸頻寬了。

要解決這個問題，大部分的影像檔案都需要先經過壓縮程序以減少檔案體積，並進一步改善效能。編碼方式 (compress decompress的縮寫) 控制了實際編解碼的方式。編碼簡單來說，就是利用某些模式消去影像中重覆的資訊，以減少檔案的體積。當影樣播放時，就重新進行解碼程序恢復原有的影像，或是盡量在螢幕上恢復原有的外觀。

選擇的編碼方式會對檔案大小以及影像的品質，造成嚴重的影響。常見的編碼方式有：Cinepak、Intel Indeo、RLE、Video 1、以及MPEG，Windows Media Player可以正常的播放這類的程式。針對不同的需要，可使用不同的編碼方式。編碼方式的說明，已經超過了本書的討論範圍。但是一般來說，Indeo之類的會損失畫面資訊的編碼方式，對於現實世界的人事物或景觀的圖像，會有比較好的效果。而RLE之類較不會損失影像品質，適合用在顏色有限的短片或動畫影片上。不過網頁上還有許多技術可以使用，所以多嘗試才能找到檔案品質與檔案大小的平衡點。

Note

這邊是一個小小的警告，因為壓縮及解壓縮需要使用同一種codec。所以客戶端的電腦中，必須擁有和你一樣的codec元件。若你使用的是非標準的codec，就必須告訴使用者哪裡可以找到這些解編碼的工具。常見的編碼方式包括有RLE、MPEG、Cinepak等等。Windows 98可用的編碼方式請參考 "控制台" 的"多媒體" 下，"裝置" 標籤中的 "視訊壓縮codec" 內容。

影像大小 影像越大，在畫面中要顯示的資料就越多。一般來說，你應該在能容忍的情況下，使用最小的影像大小。這對網頁上的多媒體應用，是非常重要的準則。大部分的編碼方式在畫面比例保持4:3的情況下，會更有效率 (也就是當畫面高度為3個像素時，寬度為4個像素)。

一般多媒體光碟或是遊戲，經常使用640 X 480，或是320 X 200的畫面。對Internet來說，這種檔案大小都太大了。Internet上可以使用160 X 120的畫面，但通常120 X 80或80 X 60效果會更好。29

播放速率 播放速率是以每秒播放的畫面數來定義 (frames per second，FPS)，這個設定對建立影像檔有非常大的影響，尤其是當使用者的頻寬很低時。當畫面速率很高時，代表需要更多的資料，但是低頻寬就代表只能接受較低的畫面播放速率。電視每秒播放30張畫面，但是即使在最理想的狀況下，Internet也不可能達到這種播放速率。一般來說每秒7張對影像來說，算是一個最低的底線。每秒7張以下可能看起來會像放幻燈片，所以最好能有10、12、或是15張。某些格式的檔案，改變播放速率並不見得會改變檔案的大小。大部分經過最佳化的動態GIF檔，並不會因為播放速率改變檔案大小。不過很不幸的，你很難掌握GIF檔的播放速率，也無法在動態GIF中加入同步的背景聲音。

顏色多寡 影像檔中所使用的顏色數量就是color depth (或是bit depth)。大部分的數位影像都是24 bit (或稱為全彩，16.7百萬色) 格式。但是還有許多的家用電腦，仍在使用8 bit (256色) 的畫面。當24 bit的影像檔在8 bit的畫面上播放時，codec程式會利用抖色 (Dither) 將顏色轉換成256色播放。抖色是利用相近的顏色，來取代原來畫面中的顏色，因此畫面會有些失真。

設計人員通常會為影像設計特定的色盤，並且希望影像能正確的套用色盤，不論在哪裡播放影像都可以獲得正確的效果。有些演算法例如RLE以及Video 1，當壓縮影像時可以指定特定的色盤。不過很有趣的是，使用指定色盤的256色影像，可能會比24 bit的全彩影像來得大。

聲音品質 在下一節中，你將會了解聲音解析度對檔案的影響。當你考量影像因素時，應該把聲音的因素也考慮進去。影像檔案通常包含聲音在裡面，通常高品質的聲音效果會使多媒體檔案變得更大。30

加入聲音

自從處理多媒體電腦出現後，聲音的技術也是一日千里，在縮小檔案體積及提高聲音品質上，有著卓越的進步。我們在這邊只能簡單介紹一下，但是你可以從音效剪輯軟體的文件，以及相關的書籍中獲得進一步的資料。下面是兩本推薦書：

The Art of Digital Audio by John Watkinson (Butterworth-Heinemann, 1994)

Principles of Digital Audio by Ken C. Pohlmann (McGraw hill, 1995)

影響聲音最重要的因素就是解析度，聲音的解析度是依據兩個要素來決定：取樣的位元數 (bit-depth)，以及取樣頻率 (frequency)。大部分的聲音編輯程式，都可以讓你設定取樣的位元數以及取樣頻率。一般來說，取樣的數字越高，代表品質越好。CD品質的取樣位元數是16，取樣頻率是44,100 Hz，通常立體聲還要兩個頻道。在將聲音轉換成在Web上使用的格式前，最好降低聲音的解析度，舉例來說：先將聲音轉換成8 bit，22,050 Hz (或11,025 Hz)，單聲道 (mono) 的狀態。

聲音編碼

你所使用的聲音編碼方式，通常會對結果造成很大的影響。舉例來說，你可使用：PCM，Lernout &Hauspie，ADPCM，IMA ADPCM，MPEG Layer 3等等。並沒有方法讓你知道哪一種對你最好，所以唯一的方式就是多嘗試以找到壓縮與品質的平衡點。31

聲音編輯軟體

通常壓縮是依靠聲音編輯軟體來處理，一些常見的工具包括有：

產品 | 何處取得 | 附記
Sound Forge | 請連接Sonic Foundry的網站32 http://www.sfoundry.com/ | 非常有彈性而且強大的工具
CoolEdit | 放置共享軟體的網站用版本 | 同時有共享軟體及商

本章簡介了Web上的多媒體使用方式，下一章將會加入一些專用工具，例如：HTML標籤、媒體控制項、以及互動式音樂控制項的使用方法。


實戰Dynamic HTML網站技術=>有關聲音與影像的進階技巧

有關聲音與影像的進階技巧
小
工
具 加入書架
加入書籤
上一章
下一章

不同的瀏覽器間，支援的聲音與影像功能也稍有不同。<BGSOUND> 標籤是在網頁中加入背景音樂最簡單的方法﹔而使用Media Player以及Interactive Music Controls就比較複雜了。本章將介紹一些這類工具的使用方法。

<BGSOUND> 標籤

利用 <BGSOUND> 標籤是在網頁中加入音樂的最快方法，不過很可惜的是只有Internet Explorer支援這種方法。程式18-1是 <BGSOUND> 標籤的使用方法：

<HTML>
<HEAD>
<TITLE>Listing 18-1</TITLE>
<BGSOUND SRC="music.wav" LOOP="infinite">
</HEAD>
<BODY>
This page demonstrates the use of the BGSOUND tag
</BODY>
</HTML>1
程式18-1

<BGSOUND> 標籤必須被放在網頁的HEAD區域中，它需要使用和 <IMG> 標籤相同的SRC屬性，以便指向媒體檔案的所在位置。<BGSOUND> 支援多種不同的媒體檔案，但是隨著作業平台的不同，實際可使用的媒體檔案也不同，WAV、MIDI以及MP3 (比較少支援) 檔案是比較常見的幾種。

BGSOUND元件有許多不同的屬性可以設定，LOOP屬性決定了聲音檔案的播放的次數，它可以接受一般的參數值。若指定 -1，聲音檔案就會一直重覆播放。BALANCE屬性值的範圍從 -10000到10000，負值代表左邊的聲音大一點，正值代表左邊的聲音要大一點，0代表左右聲道一樣大聲。VOLUME接受 -10000到0的值，而0代表相對系統的最大聲。

Note

當系統取消播放聲音的選項時，<BGSOUND> 就不能發生作用。這個選項在Internet Explorer 5的工具選單下的Internet選項/進階/多媒體的下面。在Internet Explorer 4中，則是被放置到檢視功能表下。

<IMG> 標籤以及DYNSRC屬性

Internet Explorer是唯一在 <IMG> 標籤中支援DYNSRC屬性的瀏覽器，DYNSRC可以用來指向一個影像檔案。這個方法只對avi檔案有用，而且不像OBJECT標籤這麼有彈性 (稍後會討論)。但是它很容易使用，而且當執行簡單的工作時也很有效率。程式18-2是使用這類 <IMG> 標籤的方法，圖18-1是結果。

<HTML>
<HEAD>
<TITLE>Listing 18-2</TITLE>
</HEAD>
<BODY>
<IMG DYNSRC="clouds.avi">
</BODY>
</HTML>2
程式18-2

圖 18-1 使用 DYNSRC 屬性的 <IMG> 標籤

DYNSRC屬性的功能和SRC屬性完全相同，只不過DYNSRC指向的是一個動畫檔而不是一張圖片。<IMG> 標籤也支援和 <BGSOUND> 標籤一樣的LOOP屬性，它可以指定影像檔的播放次數。-1也一樣會讓影像檔一直重覆播放。

IMG元件僅對網頁的聲音及影像功能提供有限的支援，Internet Explorer 4以後，利用媒體控制項支援了更多有關多媒體的功能。

利用媒體控制項在網頁上加入影像

在Internet Explorer 4之後，幾乎都是使用Media Player控制項來作影音播放的工作。因為這個控制項是Internet Explorer內建的控制項，所以使用者不需要再額外下載新的元件。Media Player支援常見的媒體檔案有：AVI、QuickTime、WAV、MIDI、MPEG的聲音以及影像等。程式18-3到18-6都是使用Internet Explorer的Media Player來作程式的播放工作。不過Netscape經由安裝Plug-in也可以正常的使用媒體控制項，程式18-7是有關跨瀏覽器的方法。3

Note

Internet Explorer 4原先是使用Microsoft ActiveMovie控制項，而這個控制項目前已經被功能更為強大的Media Player控制項所取代。

使用OBJECT元件

雖然前面介紹了簡單的方式，經由HTML標籤來啟動Media Player的功能。但是經由OBJECT (OBJECT或EMBED) 標籤，你能控制更多相關的屬性。當需要在網頁上使用物件時 (19章的多媒體物件也一樣)，你必須使用開始和結束標籤 <OBJECT> 和 </OBJECT>，並且加上物件的CLASSID。基本的語法如下：

<OBJECT CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
</OBJECT>

在大部分的的情況下，我們會在物件標籤中間，替物件加上ID屬性以及利用 <PARAM> 標籤控制物件的屬性。程式18-3以及圖18-2是使用Media Player控制項以及 <PARAM> 屬性設定的結果。

<HTML>
<HEAD>
<TITLE>Listing 18-3</TITLE>
</HEAD>
<BODY>
<OBJECT ID="MPlyr" CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
  <PARAM NAME="FileName" VALUE="clouds.avi">
  <PARAM NAME="AutoStart" VALUE="true">
</OBJECT>
</BODY>
</HTML>
程式18-34

圖18-2　簡單使用Media Player的範例

<PARAM> 標籤通常擁有兩個屬性說明，一個就是指定屬性的名稱，另一個就是要設定的屬性值。Media Player控制項有許多不同的屬性可供設定，例如：可設定自動播放的AutoStart屬性，及播放檔案名稱的FileName屬性。

利用 <PARAM> 或是經由Script直接呼叫物件，都可以進行修改物件屬性的工作。舉例來說： MPlyr.ShowControls = true的效果，等於利用 <PARAM NAME = "ShowControls" VALUE = "true"> 修改ID = "MPlyr" 的物件屬性。程式18-4是利用Script來設定物件屬性的範例。在這個例子中，也可以看到一些呼叫Media Player控制項的方法。

<HTML>
<HEAD>
<TITLE>Listing 18-4</TITLE>
</HEAD>
<BODY>
<OBJECT ID="MPlyr" CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
        ALIGN="left" WIDTH="320" HEIGHT="312">
  <PARAM NAME="FileName" VALUE="clouds.avi">
  <PARAM NAME="AutoStart" VALUE="-1">
  <PARAM NAME="ShowDisplay" VALUE="-1">
  <PARAM NAME="ShowControls" VALUE="-1">
  <PARAM NAME="ShowTracker" VALUE="-1">
  <PARAM NAME="PlayCount" VALUE="100">
</OBJECT>

<INPUT TYPE=button VALUE="Hide Display"
      onclick="MPlyr.ShowDisplay=false">
<INPUT TYPE=button VALUE="Show Display"
      onclick="MPlyr.ShowDisplay=true">
<BR><BR>
<INPUT TYPE=button VALUE="Show/Hide Controls"
      onclick="MPlyr.ShowControls=(MPlyr.ShowControls==true?false:true)">
<INPUT TYPE=button VALUE="Show/Hide Tracker"
      onclick="MPlyr.ShowTracker=(MPlyr.ShowTracker==true?false:true)">
<BR><BR>
<INPUT TYPE=button VALUE="Play" onclick="MPlyr.Play()">
<INPUT TYPE=button VALUE="Stop" onclick="MPlyr.Stop()">
<INPUT TYPE=button VALUE="Pause" onclick="MPlyr.Pause()">

</BODY>
</HTML>
程式18-45

在程式18-4中，媒體播放程式被內嵌在網頁中。我們使用 <PARAM> 標籤將媒體播放程式使用的參數在設計時就直接放到網頁上。也就是說當我們在撰寫網頁時，所有的參數都被放置在網頁上了。使用者可以經由按網頁上按鈕的方式，來改變相關的參數設定。這些按鈕都可藉由執行Script的方式，改變控制項的播放參數。舉例來說，按下Hide Display鈕可以將ShowDisplay屬性設為false，並停止顯示媒體檔案。而按下Show Display鈕時，則可將這個參數設為true，然後重新顯示這個媒體檔案。而Show/Hide Tracker以及Show/Hide Control使用了JScript的 ?: 運算元 (在本書的第二部份曾介紹過)，所以才能將開關的功能放置在同一個按鈕上，圖18-3是程式執行的結果。

圖18-3　利用Script來改變物件的屬性

Play、Stop、以及Pause鈕可以經由使用不同的method來改變Media Player的狀態。存取媒體播放程式功能的方法，和存取動態物件模型的方法一樣，相關的說明在 第6章 。

Media Player還有許多的功能可以使用，在表18-1中列出了其他常用的屬性設定。6

表18-1　媒體控制項屬性
屬性 | 功能描述
AnimationAtStart | 決定當媒體檔案下載時，媒體播放程式是否同步播放影像 (true/flase)
AutoRewind | 當檔案播放完畢時，是否要自動回到檔案開頭 (true/false)7
AutoStart | 是否自動播放接收到的媒體串流資料 (true/false)
Balance | 控制聲音檔案的左右平衡程度，數值範圍從 -10,000到10,000，0代表左右聲道完全平衡
Bandwidth | 以每秒播放的bits數計算目前串流媒體資料的頻寬 (唯讀)
BufferingCount8 | 代表媒體在播放時，有多少時間的資料片段被快取起來 (唯讀)
BufferingProgress | 代表有多少百分比的資料被快取起來 (唯讀)
BufferingTime | 代表有多少時間的資料被快取起來 (唯讀)
ClickToPlay | 控制當按下控制項時是否可以暫停或繼續播放 (true/false)9
CurrentPosition | 指定目前多媒體檔案的播放位置，以秒數方式表示
ConnectionSpeed | 使用者設定媒體播放程式時，所設定的連接速度 (唯讀)
DisplayBackColor | 控制播放面板的背景顏色
DisplayForeColor10 | 控制控制面板前景的文字顏色
DisplayMode | 控制播放面板顯示播放位置的方式，用秒數顯示 (0)，或是用每秒張數顯示 (1)
DisplaySize | 設定播放畫面的大小。當設為0時，播放的畫面大小和原影像一樣大、1則是對切、2是雙倍大小、3是全螢幕、4是可自動變化、5是1/16螢幕大小、6 1/4螢幕大小、7是1/2螢幕大小。
Duration | 影像短片的播放時間 (唯讀)11
EnableContextMenu | 是否可以使用滑鼠右鍵開啟媒體播放程式的快顯功能表
ErrorCode | 目前的錯誤代碼 (如果有的話) (唯讀)
ErrorDescription | 目前錯誤的文字敘述 (如果有的話) (唯讀)
FileName12 | 指定播放的媒體檔案名稱
HasError | 目前是否有錯誤 (true/false，唯讀)
ImageSourceHeight | 來源媒體的高度 (唯讀)
ImageSourceWidth | 來源媒體的寬度 (唯讀)13
LostPackets | 目前播放的串流檔案在播放時，遺失的封包數量是多少 (唯讀)
Mute | 是否要播放聲音 (true/false)
PlayCount | 檔案重覆的播放次數，0代表永遠重覆播放
PlayState14 | 裡面有目前媒體播放程式的播放狀態：0代表目前停止、1代表暫停、2代表播放中、3代表等待串流資料、4表示向前搜尋、5代表向後搜尋、6代表跳到下個標記點、7表示跳到前一個標記點、8代表串流資料未開啟 (都是唯讀資料)
Rate | 控制播放速度的指標，1代表全速，而 .75代表四分之三的速度撥放，以此類推
ReadyState | 根據目前讀取的資料，顯示媒體控制項讀取資料的狀態。1代表FileName屬性還沒設定完成、0代表檔案讀取中、3表示檔案仍在讀取中，但是已經可以播放了、4代表檔案已經下載完成了。除非ReadyState的數值是3或4，否則Run方法就不能執行
SelectionEnd | 以檔案開頭的位置計算，在多少秒後應該停止播放檔案15
SelectionStart | 以檔案開頭的位置計算，應該從多少秒時開始播放檔案
ShowControls | 是否顯示媒體控制項的控制列 (true/false)
ShowDisplay | 是否顯示媒體控制項的文字控制列說明 (true/false)
ShowGotoBar16 | 是否顯示媒體控制項的移至列 (其中包含了任何檔案中的標記位址true/false)
ShowTracker | 控制搜尋列是否顯示 (true/false)
SourceLink | 包含目前播放的短片位置 (唯讀)
StreamCount | 檔案中包含的串流媒體數量 (唯讀)17
TransparentAtStart | 控制當沒有播放媒體時，Media Player是否可以被看見 (true/false)
Volume | 控制音量大小，從 -10000 (靜音) 到0 (全開)

還有許多的屬性可以用來控制網頁上的媒體控制項，這些屬性甚至經由C++ 或是Microsoft Visual Basic的程式來修改。有關Media Player的完整屬性說明可以在Microsoft DirectX的網站 Microsoft.com/directx/dxm/help/mmp_sdk/default.htm 上面找到，或是連上MSDN的線上網頁18 msdn.Microsoft.com/resources/schurmandhtml.htm ，並選擇Media Player下相關的內容。

Media Player還支援許多的事件，包括有：buffering、click、dblclick、disconnect、displaymodechange、endofstream、error、keydown、keypress、keyup、markerhit、mousedown、mousemove、mouseup、newstream、openstatechange、playstatechange、positionchange、readystatechange、scriptcommand、warning ...等。其中最常用的事件就是readystatechange，因為這個事件決定了媒體播放程式是否能開始播放檔案。

在376頁的 程式18-4 使用了Stop、Play以及Pause方法。除此之外，媒體播放程式還支援AboutBox、Cancel、FastForward、FastReversed、GetCodecDescription、GetCodecinstalled、GetCodecURL、GetMarkerName、GetStreamSelected、IsSoundCardEnabled()、Next、Open、Pause、Play Previous、Stop、StreamSelect方法... 等。IsSoundCardEnabled() 是非常有用的方法，因為它可以用來偵測客戶端的電腦是否具有播放聲音的能力。在DirectX的網站上你能夠找到更多有關方法 (method) 以及事件 (events) 的資訊。

聲音19

若使用者的電腦上沒有音效卡，或因為種種因素沒有辦法播放音效，那麼script可能在執行時就會發生錯誤。你可以先利用Media Player的控制項測試使用者電腦系統的聲音播放能力，然後再依據測試的結果執行相關程式。程式18-5使用了IsSoundCardEnabled方法來測試使用者的音效播放能力。若偵測不到音效卡，螢幕上則會出現如圖18-4的錯誤結果給使用者看。

這個例子是一個簡單的音效卡測試回應動作，你可以對這類回應工作做進一步的加強。舉例來說，可以將使用者引導向一個新的網頁或是無法使用音效的訊息。

<HTML>
<HEAD>
<TITLE>Listing 18-5</TITLE>
<SCRIPT FOR="window" EVENT="onload" LANGUAGE="JavaScript">
  if(MPlyr.IsSoundCardEnabled()==true){MPlyr.Play()}
  else {
    alert("No sound capability available. Click OK to continue.")
  }
</SCRIPT>
</HEAD>
<BODY>
<OBJECT ID="MPlyr" WIDTH=0 HEIGHT=0
  CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
  <PARAM NAME="FileName" VALUE="music.wav">
</OBJECT>
This page plays background audio if the computer is able to
play sound,and warns the user if the computer is not.
</BODY>
</HTML>
程式18-5

圖18-4　若使用者的音效卡無法使用會顯示的對話方塊

Media Player提供了同時播放多個媒體檔案的能力，也能經由Script同時對多個媒體檔案加以控制。我們利用前一個例子的音樂範例，並且在上面再疊上其他的聲音。在圖18-5的程式18-6中，我們利用按鈕來控制聲音的播放與否，以及聲音的大小等參數。20

<HTML>
<HEAD>
<TITLE>Listing 18-6</TITLE>
<SCRIPT LANGUAGE="JavaScript">
//this function toggles a sound layer
function jToggleSnd(WhichSnd, WhichBtn, strText){
  if (WhichSnd.PlayState=="2"){
    WhichSnd.Pause()
    WhichBtn.value=("Turn "+strText+" On")
  }
  else{
    WhichSnd.Play()
    WhichBtn.value=("Turn "+strText+" Off")
  }
}
</SCRIPT>
</HEAD>
<BODY>
<!-- this is the control that plays the music -->
<OBJECT ID="MPMusic" WIDTH=0 HEIGHT=0
        CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
  <PARAM NAME="FileName" VALUE="music.wav">
  <PARAM NAME="AutoStart" VALUE="1">
  <PARAM NAME="PlayCount" VALUE="0">
</OBJECT>

<!-- this is the control that plays the voice -->
<OBJECT ID="MPVoice" WIDTH=0 HEIGHT=0
        CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
  <PARAM NAME="FileName" VALUE="voice.wav">
  <PARAM NAME="AutoStart" VALUE="1">
  <PARAM NAME="PlayCount" VALUE="0">
</OBJECT>

<H3>Layering sound files with the Media Player control</H3><P>
<INPUT TYPE=button ID=voiceBtn VALUE="Turn Voice Off"
       onclick="jToggleSnd(MPVoice, this, 'Voice')">
<INPUT TYPE=button ID=musicBtn VALUE="Turn Music Off"
       onclick="jToggleSnd(MPMusic, this, 'Music')">
<P>
<INPUT TYPE=button VALUE="Reduce Voice Volume"
       onclick="if (MPVoice.volume > -9500){MPVoice.volume-=500}">
<INPUT TYPE=button VALUE="Increase Voice Volume"
       onclick="if (MPVoice.volume < -500){MPVoice.volume+=500}">
<BR>
<INPUT TYPE=button VALUE="Reduce Music Volume"
       onclick="if (MPMusic.volume > -9500){MPMusic.volume-=500}">
<INPUT TYPE=button VALUE="Increase Music Volume"
       onclick="if (MPMusic.volume < -500){MPMusic.volume+=500}">
</BODY>
</HTML>
程式18-6

圖18-5　利用按鈕及Script，你可以分別控制聲音及背景音樂

當使用者開啟程式18-6的網頁時，兩個聲音檔案會同時開始播放。每一個聲音檔案的PlayCount都是0，所以它會一直無限重覆播放。使用者可以利用按鈕來切換兩個聲音的播放與否。我們也在每一個頻道中分別設計了音量調整鈕，以便能更精確的控制聲音的大小。

Note

目前Media Player在Windows NT 4中，並無法播放多重音訊的效果。程式18-6在Windows NT執行時並沒有什麼問題，但是只有一個聲道會發聲。

在Netscape中使用Media Player21

在Netscape 3以後的版本中，可以藉由安裝附加程式 (Plug-in) 的方式來使用Media Player的功能。程式18-7在Netscape Navigator以及Internet Explorer中，都可以正常的執行。

<HTML>
<HEAD>
<TITLE>Listing 18-7</TITLE>
</HEAD>
<BODY>
<OBJECT ID="MPlayer"
        CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
        CODEBASE="http://activex.microsoft.com/activex/controls/
                 mplayer/en/nsmp2inf.cab#Version=5,1,52,701"
        STANDBY="Loading Microsoft?Windows?Media Player components..."
        TYPE="application/x-oleobject">
        <PARAM NAME="FileName" VALUE="clouds.avi">
        <PARAM NAME="AutoStart" VALUE="true">
        <EMBED NAME="MPlayer"
               TYPE="application/x-mplayer2"
               PLUGINSPAGE="http://www.microsoft.com/Windows/
                         Downloads/Contents/Products/MediaPlayer/"
               SRC="clouds.avi">
        </EMBED>
</OBJECT>
</BODY>
</HTML>
程式18-7

媒體播放程式在Internet Explorer利用 <OBJECT> 標籤將播放程式載入網頁，在Navigator中用 <EMBED> 標籤將媒體播放程式載入網頁。而 <OBJECT> 標籤設的識別ID是MPlayer，而 <EMBED> 標籤使用NAME為MPlayer來作識別工作。在Netscape Navigator中使用Media Player，所需的設定大部分都相同 (例如MPlayer.Play())，但是在存取屬性及事件處理上兩者還是稍有不同。Netscape的外掛程式資料，可參考 Microsoft.com/directx/dxm/help/mmp_sdk/mediaplayerpluginfornetscapenavigator.htm ，或是MSDN的Media player in Navigator的內容。

互動式音樂控制項22

利用互動式音樂控制項 (Interactive Music Control) 可以讓你在網頁上加上互動式的音樂效果，而幾乎不會增加任何頻寬。它可利用Microsoft Synthesizer來製作出高品質的音樂，同時也提供比MIDI檔更高的互動性 (MIDI檔案也是另一種常見的聲音檔案格式)。

使用互動式音樂控制項時，你可以設定音樂的風格、特色、背景樂團、音樂動機、轉調、長度、種類 (Shape)、以及動態範圍 (Activity Level)等設定。每個設定，都可分別產生不同的效果。舉例來說：Band設定就可以間接指定所使用的樂器種類、音量大小、及左右聲道控制。而Shape則可控制樂器的數目及發聲數。程式18-8示範了互動式音樂控制項的使用方式：

<HTML>
<HEAD>
<TITLE>Listing 18-8</TITLE>
<OBJECT ID="IMC" CLASSID="clsid:D2377D41-E6FD-11CF-8DCF-00AA00C01802"
      CODEBASE="http://activex.microsoft.com/controls/music/IMSTUP21.CAB#version=2,1,0,14">
<PARAM NAME="Activity" VALUE="1">
<PARAM NAME="Length" VALUE="80">
<PARAM NAME="MaxCPU" VALUE="30">
<PARAM NAME="NumVoices" VALUE="10">
<PARAM NAME="Style"
       VALUE="http://www.microsoft.com/music/styles/DANCEMIX.STY">
<PARAM NAME="Personality"
       VALUE="http://www.microsoft.com/music/styles/POPDIA.PER">
<PARAM NAME="PlayImmediate" VALUE="1">
<PARAM NAME="Repeat" VALUE="1">
<PARAM NAME="Shape" VALUE="4">
<PARAM NAME="Transition" VALUE="1">
<PARAM NAME="UseSoftwareSynthesis" VALUE="0">
</OBJECT>
</HEAD>
<BODY>
This page demonstrates the Interactive Music Control.<P>
<FORM>
<INPUT TYPE="button" onclick="IMC.PlayMotif('Synth Brass')"
       VALUE="Synth Brass">
<INPUT TYPE="button" onclick="IMC.PlayMotif('Orch Hits')"
       VALUE="Orch Hits">
</FORM>
</BODY>
</HTML>
程式18-8

這個程式需要連上網路才能執行，因為它需要從 http://www.microsoft.com/ 下載兩個檔案。這個程式示範了如何利用 <PARAM> 標籤及Script來控制互動式音樂控制項。當控制項下載後，<PARAM> 標籤會先設定好相關參數，指定要播放哪些檔案以及播放方式。而使用者可透過按鈕執行Script的方式，改變音樂的動機以達成互動音樂的效果。23

Note

譯註：因為原始元件已經被移動過了，所以相關資料請參考 www.microsoft.com/music 下有關Direct Music的說明文件。

在Microsoft.com/music下面，可以找到更多有關互動式音樂控制項的資料、說明、範例、簡介、以及未來在Netscape Navigator上的發展方向等資料。

到目前為止，我們已經將傳統的影音多媒體表現方式簡介過一遍了。在下一章中，我們將認識DirectAnimation Multimedia控制項，它可以利用事件控制及劇本編排的方式，製作出更複雜的多媒體效果。

實戰Dynamic HTML網站技術 視窗縮放
有關聲音與影像的進階技巧


實戰Dynamic HTML網站技術=>DirectAnimation 多媒體控制項

DirectAnimation 多媒體控制項
小
工
具 加入書架
加入書籤
上一章
下一章

Microsoft將許多特殊的ActiveX多媒體控制項加入了Internet Explorer中，但目前Netscape Navigator並不直接支援這些多媒體控制項。這些控制項是設計用來幫助網頁設計者在低頻寬的情況下，做出多媒體的效果。同時網頁不論在設計時或是顯示在客戶端的電腦後，都可以做即時的動態改變。因為經由這些控制項所做出的圖片或是特效，都可以經由修改Script的方式做改變。所以它可以提供連Macromedia Flash都無法做到的程式控制能力。在本章中，我們將會介紹在Internet Explorer所附加的多媒體控制項，以及如何利用它們來作出有趣的多媒體網頁。

DirectAminmation 多媒體控制項其實是一組ActiveX控制項的統稱，每個控制項各負責不同的功能。它有提供Web的開發人員下列的服務：

  • DirectAnimation控制項不需要像其他的控制項自網路上執行下載的工作，因為它已經內建在Internet Explorer中了。
  • DirectAnimation控制項不需要佔住固定的視窗位置，也就是說它可以提供與其他網頁元件更高的互動性。舉例來說：你可以建立一個透明背景的物件，然後依然可看到背景文字。1
  • DirectAnimation控制項可以結合點陣圖與向量圖，製作複雜的動畫效果。

DirectAnimation控制項包括有Structured Graphics控制項、Sequencer控制項、Path控制項、以及Spite控制項。有關這些控制項的進一步說明可以參考 Microsoft.com/directx/dxm 並選取DirectAnimation的連結。首先我們將從Structured Graphics控制項，開始一一為您介紹。

Structured Graphics控制項

Structured Graphics控制項提供了快速有效的方式，可讓您在網頁文件中，加入簡單的圖形。Structured Graphics圖形本身是向量的格式 (代表圖形是由線條及曲線所組成的，而不是JPG或GIF類的圖素畫面)。跟傳統的圖片比較起來，這些圖案只會佔用非常小的體積。

Direction控制項何其他的ActiveX控制項一樣，在使用前需要將在網頁中宣告，使用控制項的基本語法如下：2

<OBJECT
  ID=ObjectID
  CLASSID="CLSID:369303C2-C7AC-83D5-00A0C90833E6"
  STYLE="height: xx; width: xx ; [styleProperty : xx]">
  <PARAM NAME="PropertyName" VALUE="PropertyValue">
</OBJECT>

我們先看看每一行的程式碼，首先注意所有的宣告都被放在 <OBJECT> 與 </OBJECT> 標籤之間，藉由此種方式來辨別網頁中不是屬於HTML的元件。ID屬性宣告了物件的名稱，方便從Script中使用這些元件。雖然ID屬性不是必須的，但是你將會發現若不定義ID屬性將會很難從Script中使用此元件，使得元件發揮的功能受到限制。

每個ActiveX控制項都有一個全世界獨一無二的識別碼CLSID，並藉此告知瀏覽器物前所使用的元件是哪一個。不過你並不用去記這漫長的16進位數字，只要使用時將CLSID數字複製到所需使用的網頁上就可以了。為了幫助你快速進入情況，在書附光碟的第19章光碟目錄下有一個da_id.txt檔，裡面有DirectAnimation控制項中所有的CLSID，以及它們的易記名稱。許多HTML的編輯程式，包括有Microsoft FrontPage，Microsoft Visual Interdev，都可以直接選取清單中物件的方式，來將物件 (以及它們的CLSID) 加入網頁中。

STYLE屬性其實也不是完全必要的屬性，但是它的用處很多。它可以用來設定Structured圖片物件的高度以及寬度 (獨立於其內含物件的設定)。為了避免其內的物件不小心被遮住，你必須妥善的設定Structured圖片物件的尺寸。舉例來說，若一個100點寬的物件裡面卻有300點寬的圖形，會感覺裡面的圖型好像被切掉了。在預設狀況下，所有Structured Graphics物件裡面的圖形，都是從中間開始繪出。所以在沒有經過計劃的情形下，你可能會發覺圖案的右邊或是下面被Structured Graphic物件給切割掉了。你可以利用本章稍後討論的ExtentHeight跟ExtentWidth參數，來避免此種情況的發生。STYLE屬性可用來設定物件擺放的位置，以及其z軸座標，以便製作出物件重疊的效果。

PARAM標籤可以讓你設定許多的參數，以便控制物件的行為。同時 <PARAM> 標籤也可以讓你呼叫一個特定控制項的方法 (method)。PARAM標籤的NAME屬性可以設成一個屬性名稱 (如HighQuality)，或是行號 (如Structured Graphics中的線段編號)。而VALUE部分則是要設定給屬性的值或是要使用的特殊方法。每個物件能用的屬性和方法都不相同，即使有時候它們的名稱會發生重覆的情形，但是實際上對每個物件來說意義都不一樣。

程式19-1式一個簡單的Structured Graphics物件，裡面有一個矩形，圖19-1就是執行的結果。

<HTML>
<HEAD>
<TITLE>Code Listing 19-1</TITLE>
</HEAD>
<BODY>
<OBJECT
  ID="square"
  CLASSID="CLSID:369303C2-D7AC-11D0-89D5-00A0C90833E6"
  STYLE="height: 102; width: 102">
  <PARAM NAME="Line0001" VALUE="SetLineColor(0,0,255)">
  <PARAM NAME="Line0002" VALUE="SetLineStyle(1,2)">
  <PARAM NAME="Line0003" VALUE="SetFillStyle(11)">
  <PARAM NAME="Line0004" VALUE="SetFillColor(0,0,255,255,196,196)">
  <PARAM NAME="Line0005" VALUE="Rect(1,1,100,100,0)">
  <PARAM NAME="ExtentTop" VALUE="0">
  <PARAM NAME="ExtentLeft" VALUE="0">
</OBJECT>
</BODY>
</HTML>3
程式19-1

圖19-1　一個簡單的矩形加上漸層的效果
Note

許多的屬性和方法需要使用到行號，這些設定才可以依照行號的順序執行。這種依序執行的方式有許多的功用，以現實生活的例子來說：

  1. 轉向以面對北方
  2. 伸長在西邊的手臂
  3. 轉向南方4

在這個例子中，你最後發現舉起的是右手。若將步驟1到步驟3反過來，將會發現最後舉起的將是左手。

譯註：Internet Explorer 5預設是沒有安裝Direct Animation控制項的，您必須先行安裝此控制項才能正常瀏覽本章的範例。

這個程式示範了建立Structured Graphics的技巧 (本章稍後將會討論如何由現有的圖案建立Structured Graphics)。最前面的兩個 <PARAM> 標籤建立了矩形週邊的線條。第1個 <PARAM> 標籤以紅、綠、藍3種原色設定線條的顏色，我們將紅色及綠色都設為0 (因此沒有紅色或綠色)，而藍色設為255 (最大值)，所以矩形物件四周的線就是藍色。第2個 <PARAM> 標籤則是設定線條的樣式，1代表實線、2代表虛線、而0代表看不到任何線段。而在SetLineStyle方法的第2個數值是設定線條的寬度。接下來的兩個 <PARAM> 標籤設定了圖形內填入的樣式及填入的顏色。SetFillStyle方法有許多不同的填入樣式，相關的資料列在下表中。我們使用編號11的方法來製作由藍到紅的漸層效果。

樣式 | 代表數值
不填色 | 05
單色 | 1
水平條紋 | 3
垂直條紋 | 4
左上到右下條紋6 | 5
右下到左上條紋 | 6
交錯方格條紋 | 7
對角交錯條紋 | 87
水平漸層 | 9
垂直漸層 | 10
放射狀漸層 | 11
直線漸層8 | 12
矩形漸層 | 13
依照形狀漸層 | 14

再下來一個 <PARAM> 標籤使用Rect方法來畫出一個矩形，矩形算是 Structured Graphics的基本圖形，利用這些基本圖案我們就可以製作出更複雜的圖形。製作基本圖形的方法請參考下表。

方法9 | 形狀描述
Arc | 畫一個圓形或是一個橢圓弧
Oval | 橢圓形
Pie | 切割過的圓形10
Polygon | 多邊型
Polyline | 多段的線條
Polyspline | 多點間的平滑連線
Rect11 | 矩形
RoundRect | 平滑四角的矩形
Text | 將文字字串視為Structured Graphics處理

因為每一個圖案都不一樣，所以每個方法的用途也不一樣。可以在 microsoft.com/directx/dxm/help/da/ref_cntrl/controls_oview.htm12 以及MSDN的線上網頁 msdn.Microsoft.com/resources/schurmandhtml.htm 下，選擇Structured Graphics Overview的內容。

最後兩個 <PARAM> 標籤則設定了ExtentTop以及ExtentLeft屬性。這兩個屬性和CSS的top和left相當類似。將這兩個數值設為0時，會讓圖形從Structured Graphics物件的左上角開始計算及繪製圖形。其他類似的屬性還有ExtentHeight以及ExtentWidth，這兩個屬性能在Structured Graphics物件內，設定圖形的高度與寬度。不過只有在設定了ExtentTop以及ExtentLeft屬性的情況下，才能使用這兩個屬性。其他能經由 <PARAM> 以及Script設定的Structured Graphics物件屬性如下表。

屬性 | 功能描述
CoordinateSystem13 | 控制y值0從頁面最上方開始計算 (預設的數值0)，或是由頁面的底端開始設定 (數值1)
HighQuality | 開啟反鋸齒補償 (數值1)，或關閉 (數值0)
MouseEventsEnabled | 控制圖形上的滑鼠事件是否被處理 (數值1) 或是不被處理 (預設值，數值0)
PreserveAspectRatio | 控制物件的外觀是否會依比例放大，數值1是代表會保持比例縮放，數值2代表不會依比例縮放 (預設值)14
SourceURL | 讓Structured Graphics控制項使用外部的檔案

許多控制項的屬性，需要經過Script才能進行控制，直接控制Structured Graphics控制項能做到的功能比控制Direct Animation控制項更多。不過由於技術太過複雜，本書不會另外詳細說明。

快速建立Structured Graphics控制項的方法

從前面一個例子中，您可以知道要建立一個複雜的Structured Graphic，需要以正確的順序，撰寫數百個 <PARAM> 標籤。想也知道這不是一件容易的事。但是目前可以用轉換的方式將Windows Metafiles (附檔名為 .wmf的檔案)，變成structured graphics的檔案。許多的商用繪圖軟體，例如Corel Draw!，Adobe Illustrator，Microsoft Power Point，Havard Graphics..等。都支援WMF的檔案格式。 Microsoft Office中，也有許多WMF格式的美工圖片供您使用。

要在網頁上使用WMF格式的檔案，您可以使用書附光碟 /tools/ 目錄下的圖檔轉換格式的檔案，變成Structured Graphics所需的 <PARAM>。要進行轉換的工作很簡單，只要開啟要轉換的WMF檔案，然後設定所要使用的選項，然後另存新檔案就可以了。接著，利用Source URL來指定 <PARAM> 的來源位址。

向量圖片的優點15

最常見的兩種電腦圖檔格式，分別是向量圖及點陣圖。大部分常見的圖檔格式都是點陣圖，例如BMP或是GIF圖檔都是屬於此類。點陣圖圖案中的每一點，都是圖案的一部分資訊。向量圖則是由一連串的線段及曲線所組成的，此種圖檔的資訊都是被存成一連串的直線和曲線資料，而不是儲存單點的資訊。

向量圖和點陣圖最大的不同點，在於點陣圖可以隨意的放大、縮小、旋轉，但是不會破壞原來圖案的特性。如果你對一個點陣圖作過多的放大縮小動作，或是縮放比例過大時，圖形的邊緣就會變得很粗糙，我們在最後會介紹一個比較複雜的structured Graphics例子，程式19-2是所需的敘述，圖19-2是最後顯示的結果。

<HTML>
<HEAD>
<TITLE>Code Listing 19-2</TITLE>
</HEAD>
<BODY>
<INPUT TYPE=button VALUE="Bigger" onclick="Idea.Scale(1.2,1.2,0)">
<INPUT TYPE=button VALUE="Smaller" onclick="Idea.Scale(.8,.8,0)">
<BR>
<OBJECT ID="Idea" STYLE="width: 400; height: 400"
  CLASSID="CLSID:369303C2-D7AC-11D0-89D5-00A0C90833E6">
  <PARAM NAME="Line0001" VALUE="SetLineColor(0,0,0)">
  <PARAM NAME="Line0002" VALUE="SetFillColor(255,255,0)">
  <PARAM NAME="Line0003" VALUE="SetLineStyle(6,1)">
  <PARAM NAME="Line0004" VALUE="Polygon(20,-6,-67,-6,-71,-7,-74,-8,-76,
    -10,-79,-10,-82,-9,-84,-6,-86,-4,-87,-2,-86,-1,-86,1,-84,2,-82,2,-79,
    0,-77,-2,-73,-2,-71,-2,-69,-3,-67,-4,-65)">
  <PARAM NAME="Line0005" VALUE="SetLineColor(0,0,0)">
  <PARAM NAME="Line0006" VALUE="SetFillColor(0,0,0)">
  <PARAM NAME="Line0007" VALUE="SetLineStyle(0,1)">
  <PARAM NAME="Line0008" VALUE="Polygon(5,-14,-84,-22,-85,-23,-87,-22,
    -88,-21,-88)">
  <PARAM NAME="Line0009" VALUE="Polygon(5,-10,-92,-14,-96,-14,-98,-12,
    -99,-11,-97)">
  <PARAM NAME="Line0010" VALUE="Polygon(5,-1,-92,-2,-98,0,-100,2,-100,
    1,-98)">
  <PARAM NAME="Line0011" VALUE="Polygon(5,5,-89,11,-94,13,-93,13,-92,
    12,-91)">
  <PARAM NAME="Line0012" VALUE="Polygon(21,1,-48,-3,-54,-7,-58,-12,-58,
    -17,-55,-20,-52,-21,-47,-20,-40,-17,-33,-11,-28,-6,-26,-2,-25,2,-26,
    4,-28,5,-33,5,-39,3,-44,12,-48,12,-50,12,-51,3,-46)">
  <PARAM NAME="Line0013" VALUE="Polygon(38,11,-27,6,-23,4,-22,3,-19,5,
    -16,6,-15,11,-17,19,-23,25,-30,32,-38,32,-41,32,-50,30,-64,32,-72,
    32,-75,31,-77,28,-78,26,-80,28,-87,27,-89,25,-88,24,-79,24,-76,23,
    -75,20,-76,17,-76,17,-74,19,-73,22,-73,24,-71,26,-69,27,-64,28,-55,
    28,-47,28,-40,26,-38,20,-33,14,-30)">
  <PARAM NAME="Line0014" VALUE="Polygon(35,-6,-20,-9,-21,-15,-21,-20,-17,
    -28,-8,-32,-1,-32,1,-30,6,-26,8,-20,10,-16,12,-14,14,-15,16,-18,20,
    -22,20,-25,19,-27,20,-26,22,-23,23,-18,23,-14,22,-11,20,-10,17,-9,14,
    -11,11,-16,9,-22,8,-26,5,-28,2,-27,-2,-23,-8,-19,-11,-12,-14,-6,-15,
   -6,-18)">
  <PARAM NAME="Line0015" VALUE="Polygon(20,11,-6,8,-16,5,-21,-1,-23,-7,
    -22,-10,-17,-9,-10,-8,0,-8,10,-10,18,-11,22,-10,26,-7,28,-3,30,0,31,
    5,31,10,27,14,18,14,11,11,2)">
  <PARAM NAME="Line0016" VALUE="Polygon(28,0,22,-5,21,-8,22,-9,26,-8,49,
    -8,54,-10,64,-10,75,-9,81,-10,84,-16,89,-18,95,-18,97,-13,100,-12,99,
    -12,95,-10,90,-8,87,-6,86,-4,83,-3,82,-5,80,-6,79,-7,74,-6,63,-3,52,
0,42,1,31)">
<PARAM NAME="Line0017" VALUE="Polygon(31,12,31,12,24,8,21,3,21,2,24,3,
    30,5,40,8,47,10,56,11,64,11,71,10,76,8,77,8,79,10,81,13,82,17,82,26,
    84,28,87,32,86,33,81,32,80,25,79,17,79,14,79,13,76,14,72,14,64,13,55,
    12,44,12,34)">
</OBJECT>
</BODY>
</HTML>
程式19-2

16
圖19-2　整個網頁連圖只要2.67KB

整個網頁連圖只要2.67KB, 同時還可隨意的放大縮小，利用頁面左上角的按鈕，你可以即時的改變圖案的大小，不需要重新載入頁面來完成圖案的更新工作。我們是利用Stuctured Graphics控制項的scale方法來變更圖形x，y，z軸的大小。在程式碼19-2中，我們在x，y方向作等比例的放大。但是你可以嘗試看看在不同的方向作不同比例改變效果，圖案就會產生不同的延伸效果。除了Scale方法外，Structured Graphics控制項還支援許多不同的方法，例如Clear、Rotate、Translate (移動圖形)，SetIdenity (重設圖形)，以及Transform 4 x 4同時進行Scale、Rotate、Translate的動作。

程式19-3使用了程式19-2的圖形，但是在畫面中我們加上了旋轉、停止旋轉，及恢復原狀3個按鈕。

<HTML>
<HEAD>
<TITLE>Code Listing 19-3</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var Xint,Yint,Zint
function SpinIt(degX,degY,degZ){ Idea.Rotate(degX,degY,degZ) }
</SCRIPT>
</HEAD>
<BODY>
<INPUT TYPE=button VALUE="RotateX"
  onclick="clearInterval(Xint);Xint=setInterval('SpinIt(20,0,0)',0100)">
<INPUT TYPE=button VALUE="RotateY"
  onclick="clearInterval(Yint);Yint=setInterval('SpinIt(0,20,0)',0100)">
<INPUT TYPE=button VALUE="RotateZ"
  onclick="clearInterval(Zint);Zint=setInterval('SpinIt(0,0,20)',0100)">
<BR>
<INPUT TYPE=button VALUE=" Stop  X " onclick="clearInterval(Xint)">
<INPUT TYPE=button VALUE=" Stop  Y " onclick="clearInterval(Yint)">
<INPUT TYPE=button VALUE=" Stop  Z " onclick="clearInterval(Zint)">
<INPUT TYPE=button VALUE="Initial Position" onclick="Idea.SetIdentity()">
<BR>
<OBJECT ID="Idea" STYLE="width: 250; height: 250"
  CLASSID="CLSID:369303C2-D7AC-11D0-89D5-00A0C90833E6">
  <PARAM NAME="Line0001" VALUE="SetLineColor(0,0,0)">
  <PARAM NAME="Line0002" VALUE="SetFillColor(255,255,0)">
  <PARAM NAME="Line0003" VALUE="SetLineStyle(6,1)">
  <PARAM NAME="Line0004" VALUE="Polygon(20,-6,-67,-6,-71,-7,-74,-8,-76,
    -10,-79,-10,-82,-9,-84,-6,-86,-4,-87,-2,-86,-1,-86,1,-84,2,-82,2,-79,
    0,-77,-2,-73,-2,-71,-2,-69,-3,-67,-4,-65)">
  <PARAM NAME="Line0005" VALUE="SetLineColor(0,0,0)">
  <PARAM NAME="Line0006" VALUE="SetFillColor(0,0,0)">
  <PARAM NAME="Line0007" VALUE="SetLineStyle(0,1)">
  <PARAM NAME="Line0008" VALUE="Polygon(5,-14,-84,-22,-85,-23,-87,-22,
    -88,-21,-88)">
  <PARAM NAME="Line0009" VALUE="Polygon(5,-10,-92,-14,-96,-14,-98,-12,
    -99,-11,-97)">
  <PARAM NAME="Line0010" VALUE="Polygon(5,-1,-92,-2,-98,0,-100,2,-100,
    1,-98)">
  <PARAM NAME="Line0011" VALUE="Polygon(5,5,-89,11,-94,13,-93,13,-92,
    12,-91)">
  <PARAM NAME="Line0012" VALUE="Polygon(21,1,-48,-3,-54,-7,-58,-12,-58,
    -17,-55,-20,-52,-21,-47,-20,-40,-17,-33,-11,-28,-6,-26,-2,-25,2,-26,
    4,-28,5,-33,5,-39,3,-44,12,-48,12,-50,12,-51,3,-46)">
  <PARAM NAME="Line0013" VALUE="Polygon(38,11,-27,6,-23,4,-22,3,-19,5,
    -16,6,-15,11,-17,19,-23,25,-30,32,-38,32,-41,32,-50,30,-64,32,-72,
    32,-75,31,-77,28,-78,26,-80,28,-87,27,-89,25,-88,24,-79,24,-76,23,
    -75,20,-76,17,-76,17,-74,19,-73,22,-73,24,-71,26,-69,27,-64,28,-55,
    28,-47,28,-40,26,-38,20,-33,14,-30)">
  <PARAM NAME="Line0014" VALUE="Polygon(35,-6,-20,-9,-21,-15,-21,-20,-17,
    -28,-8,-32,-1,-32,1,-30,6,-26,8,-20,10,-16,12,-14,14,-15,16,-18,20,
    -22,20,-25,19,-27,20,-26,22,-23,23,-18,23,-14,22,-11,20,-10,17,-9,14,
    -11,11,-16,9,-22,8,-26,5,-28,2,-27,-2,-23,-8,-19,-11,-12,-14,-6,-15,
    -6,-18)">
  <PARAM NAME="Line0015" VALUE="Polygon(20,11,-6,8,-16,5,-21,-1,-23,-7,
    -22,-10,-17,-9,-10,-8,0,-8,10,-10,18,-11,22,-10,26,-7,28,-3,30,0,31,
    5,31,10,27,14,18,14,11,11,2)">
  <PARAM NAME="Line0016" VALUE="Polygon(28,0,22,-5,21,-8,22,-9,26,-8,49,
    -8,54,-10,64,-10,75,-9,81,-10,84,-16,89,-18,95,-18,97,-13,100,-12,99,
    -12,95,-10,90,-8,87,-6,86,-4,83,-3,82,-5,80,-6,79,-7,74,-6,63,-3,52,
    0,42,1,31)">
  <PARAM NAME="Line0017" VALUE="Polygon(31,12,31,12,24,8,21,3,21,2,24,3,
    30,5,40,8,47,10,56,11,64,11,71,10,76,8,77,8,79,10,81,13,82,17,82,26,
    84,28,87,32,86,33,81,32,80,25,79,17,79,14,79,13,76,14,72,14,64,13,55,
    12,44,12,34)">
</OBJECT>
</BODY>
</HTML>
程式19-3

圖19-3　這個圖形可沿著任意軸旋轉17

以上的程式使用了Structured Graphics控制項的Rotate以及SetIdentity方法。Rotate方法可以將圖形沿著x，y， z軸，依照指定的角度進行旋轉。Rotate X，Rotate Y，Rotate Z按鈕中，都有類似的OnChick事件處理器。

onchick = "clearInterval" (Xint);Xint= SetInterval ('SpinIt (20,0,0)',0100)"

我們利用了SetInterval以及ClearInterval來對事件做處理。Internet Explorer以及Netscape都支援Windows物件下的SetInterval方法，它可以在指定的時間過完後，繼續執行指定的動作。在本例中，每100微秒我們就呼叫SpinIt函數，由SpinIt函數負責圖形的旋轉工作。因為SetInterval會重複旋轉的工作，所以圖形看起來就是在不停的的轉動。Xint變數用來記錄SetInterval方法使用的計時物件；這稍後會被clearInterval用來移除原先的旋轉狀態。Initial Dosition鈕會使用SetIdentity方法來將圖形恢復至原先的狀態。

Structured Graphics控制項有許多有用的事件可以使用。包括有onchick、ondbchick、onmousedown、onmousemove、onmouseout、onmouseover、以及onmouseup。

利用一個Script區塊來捕捉事件

捕捉Direct Animation控制項事件最好的方法，就是利用一個Script區塊來捕捉事件。舉例來說，我們可以利用以下的Script，捕捉Idea物件上的on mouseout事件。

<SCRIPT LANGUAGE="JavaScript" FOR="Idea" EVENT="onmouseout">
 [Event handling script here]
</SCRIPT>18

本段只是簡單示範了Structared Graphics控制項的使用方法，當然你還可以進一步的使用其他方法及屬性來做進一步的控制工作。有關Strrctared Graphics的進一步說明，請參考 microsoft.com/directx/dxm 下的Multimedia控制項下的Direct Animation說明。

Sequencer控制項

Sequencer控制項可以控制網頁上的動作的發生時間。這個控制項可以提供比SetInterval以及set Timeout更多的控制能力。Sequencer控制項也需要和Structured grophics控制項一般的 <OBJECT> 標籤，它的CLASSID如下：

CLASSID="CLSID:B0A6BAE2-AAF0-11D0-A152-00A0C908DB96"

程式19-4是倒數計時了，然後在螢幕上顯示Ta Da的結果!19

<HTML>
<HEAD>
<TITLE>Code Listing 19-4</TITLE>
<OBJECT ID="Seq1" CLASSID="CLSID:B0A6BAE2-AAF0-11D0-A152-00A0C908DB96">
</OBJECT>

<SCRIPT LANGUAGE="JavaScript">
Seq1.Item("ActionSet1").At(0.000,"showText('3')",1,0.050,1);
Seq1.Item("ActionSet1").At(1.000,"showText('2')",1,0.050,1);
Seq1.Item("ActionSet1").At(2.000,"showText('1')",1,0.050,1);
Seq1.Item("ActionSet1").At(3.000,"showText('Ta Da!')",1,0.050,1);

function showText(obj){ Span1.innerHTML=obj }
</SCRIPT>
</HEAD>
<BODY onload="Seq1.Item('ActionSet1').Play()">
<CENTER>
<SPAN ID="Span1" STYLE="font:48pt bold arial;color:red"></SPAN>
</CENTER>
</BODY>
</HTML>
程式19-4

Sequencer控制項是利用一連串的動作，來綿編排網頁上的動作順序。我們利用At方法，來指定動作發生時間，以下是At方法的語法：

ObjectID.Item("ActionSetn".At(time,"script",[loop, Interval, tiebreak, dro[ threshold])

你必須在time以及script中，提供相關的引數以供使用，方括孤內的4個引數是可選擇性的使用 (實際使用時，不要真的把方括弧加入敘述中。以下是這些引數的使用方法：

  • time引數可以指定動作的開始時間，計算的基準是以動作的開始時間計算。引數的格式是ss:mss (秒:微秒)。
  • 使用Script引數來指定要執行的程式 (Procedured)。通常都會將這個引數指向一個函式。你可以在At方法中，直接使用eval或window.execScript而不需指定函數名稱。舉例來說，在程式19-4中，我們使用了如下的敘述，而非使用showetext ('Ta Da!')。20

    Seq1.Item("ActionSet1").At(3.000,"eval(\"Span1.innerhHTML='Ta Da!'\")", 1,.050,1);
  • 使用loop引數來指定動作的次數。當數值為0時，會停止動作的執行。任何正整數代表要執行的次數， -1代表不斷的重覆執行。任何其他的負數都會當成0， 並停止執行程式。
  • 使用interval引數來指定動作的間隔時間，預設值是33微秒 (00.033) ，或是每秒30個畫面。引數的格式是ss.mss (秒, 微秒)
  • 使用tiebreak來指定動作的優先順序。如果同時有兩個動作同時發生，比較小的tlebreak正整數會最先被執行。預設值 -1代表這個動作將會最後被執行。
  • 使用drop threshold引數來指定當動作沒有執行時，何時可以捨去這個動作。預設值是負1，代表永遠不捨去這個動作。這個引數的格式是ss:mss (秒, 微秒)。

程式19-4首先建立了一連串的動作，一旦文件載入後呼叫PLAY方法，所有動作就會依序被執行。每一秒鐘ShowText函數都會被呼叫一次，並且改變SPAN元件內容。您可以利用動作再去呼叫另一個動作，以製作出複雜的動作。

Sequencer控制項也支援stop，pause，以及seek方法，stop方法會停止動作的執行並且清除執行過的動作紀錄，pause會暫停動作的執行，但會保存執行過的動作紀錄，seek可讓您快速往前或是往後選取的動作，您可以利用playstate屬性來告知哪一個動作正在暫停，播放或是停止狀態。Time屬性可讓您得知已經經過的時間。onplay，onpause，onstop ，以及onseek事件則會在事件發生的時候 － 被觸發。當Sequencer控制項完成載入記憶體的手續時，則會觸發oninit事件。21

Note

當您使用VBScript時，使用的程式語法會稍有不同。在Jscript中, 當使用到一個動作時，Item的用法是這樣的：Seq1.Item('ActionSet1')。舉例來說，Play函數的呼叫方法是這樣的：Seq1.Item('ActionSet1').play()。在VBScript中，並不會使用Item項目，所以語法會變成Seq1('ActionSet1')play()。

Path控制項

Path控制項提供一個物件移動的快速有效方法。這個控制項可以定義出幾乎任何路徑形狀，並且讓物件沿著我們所指定的路徑移動，同時還可以設定動作的方向，以及動作持續的時間。甚至可以在路徑上設定特殊標記，以方便呼叫物件處理程式。

您還是必須在網頁中上對應的 <Object> 標籤，Path控制項的CLSID如下:

CLASSID="CLSID:D7A7D7C3-D474-11D0-89D3-00A0C90833E6"

<PARAM> 標籤可以控制Path控制項的行為。舉例來說：可以控制運動的方向，以及物件是自動在路徑上移動，或是需要經由script來啟動。以下是Path控制項可以使用的屬性。

屬性22 | 功能
AutoState | 指定當路徑被載入時，是否會自動執行 (-1是true，0是false)
Bounce | 指定當物件移動到路徑的終點時，會發生的行為。若設定成1或true，物件將會往反方向沿著原路移動回去，若是設定成0或false，物件抵達路徑終點站
Direction | 設定路徑是沿著正在向移動 (0)，或許反向移動 (1)23
Duration | 指定路徑上的行徑時間有多長, 格式為ss:mss (秒;微秒)
PlayState | 會回應路徑目前的移動狀態。PlayState會傳回以下3個數值之一。0代表路徑正在停止狀態，1代表正在路徑上移動。2代表在暫停狀態。這個屬性是唯讀屬性。
Repeat | 指定物件在路徑上的移動次數，0代表不使用Report屬性，-1代表保持重複移動。預設的Repeat數字是1。
Target24 | 指定在路徑上移動的物件 (使用物件的ID屬性來指定物件)
Time | 回應物件已經在路徑上移動了多少時間。
TimeInterval | 指定路徑的更新時間。

程式19-5利用Path控制項讓物件沿著橢圓型路徑移動。

<HTML>
<HEAD>
<TITLE>Code Listing 19-5</TITLE>
<OBJECT ID="pthOval"
CLASSID="CLSID:D7A7D7C3-D47F-11D0-89D3-00A0C90833E6">
  <PARAM NAME="AutoStart" VALUE="true">
  <PARAM NAME="Repeat" VALUE="2">
  <PARAM NAME="Bounce" VALUE="true">
  <PARAM NAME="Duration" VALUE="7">
  <PARAM NAME="Shape" VALUE="Oval(100,75,300,200)">
  <PARAM NAME="Target" VALUE="Text1">
</OBJECT>
</HEAD>
<BODY>
<SPAN ID="Text1" STYLE="position:absolute">An Oval Path</SPAN>
</BODY>
</HTML>25
程式19-5

當程式19-5的網頁被載入網頁後。物件自動會在路徑上移動。移動的時間大概在7秒中內結束。這個例子使用Path控制項的Oval方法來定義物件的行動路徑。Path控制項有許多有用的方法，可參考下頁的列表：

方法 | 功能
Oval | 建立一個Oval型的物件，使用的格式和strctured Graphics的Oval方法相同。
Polygon26 | 建立一個多邊型的封閉路徑供移動使用。
PolyLine | 有多條直線組成一個路徑。
Rect | 建立一個矩形路徑，和Structured Graphics控制項的Rect方法相同。
Spline | 從多項式所製作出的曲線及定位點中，製作出所需的路徑。27
Play | 從目前開始在路徑上移動。
Stop | 停止移動並回到原點。
Pause | 停止移動，但保持移動經過的時間。
Seek28 | 將時間移到某一定點。
AddTimeMaker | 設定一個可以觸發onmaker事件的標記，當物件移動到此點時，就會觸發onmaker事件在HTML碼 <PARAM NAME="AddTimeMaker" VALUE="3,MakerTest,true"> 中，我們在原播放程序中加上一個MakerTest標記在第3秒的地方。當設定值為true時，代表與此標記相關的事件將會被觸發，相等的Jscript敘述像是PthOval.AddTimeMaker(3,"MakerTest,true")。
KeyFrame | 設定路徑上的X，Y位置，並指定到達的時間。它可經由Script來進行設定 keyframe Array=new Array(X1,y1,x2,y2..XN,yN) TimeArray=new Array(Time2, Time3,...TimeN)29 PthCtrl.keyframe(N,keyframeArray,TimeArray

Path控制項也支援許多有用的事件，例如：onplay，onpause，onstop，onseek事件將會在控制項狀態改變時被觸發。當物件移動AddTimeMaker方法所設定的事件時，onmarker及onplaymaker事件會被觸發。它們不同點在於onplaymaker事件是在經過標記時被觸發，而onmaker事件是在用seek方法移動該點時觸發。

Sprite控制項

如果您對於傳統的動畫技術有所了解，您就應該知道動畫是由一連串的分隔畫面連續播放所組成的。每一個靜止畫面都和前一張稍有不同，當動畫依序播放時，看動畫的人就會感覺畫面真的在動一樣。

DirectAnimation Sprite控制項可以讓Web的開發人員有更多的方式，可以控制播放方式以及動畫的行為。但是它仍然是由一個單一的動畫檔案中，依序播放所有影片所組成。但是Sprite控制項可以讓您對於傳統的動態GIF檔案做更多的控制。舉例來說，您可以移到特定的一格畫面上，或是改變每格畫面的播放速度。

和其它的DirectAnimation控制項一樣。必須要先在網頁中加上CLSID才能正常動作，Sprite控制項的CLSID如下:

CLASSID="CLSID:FD179553-D86E-11D0-89D6-00A0C908333E6"30

Srite控制項支援許多不同的事件，從動畫檔案的來源位置到特明色的控制，都包含在內，以下是一些常見的屬性：

屬性 | 說明
Autostart | 指定控制項載入網頁時是否自動播放。
Colorkey | 設定來源圖片的透明色。31
UseColorKey | 指定sprite控制項的透明資訊是否使用。
Frame | 回應目前播放的frame是哪一張。
Initial Frame | 設定當可以看到控制項後，看到的是哪一張frame。
Final Frame32 | 設定當播放結束時，可以看到的frame是哪一張。
FrameMap | 設定重播frame的順序，以及每張frame播放時間。格式是frame1,time1; frame2, time2 (1, .100; 2.100; 3.100)。
NumFrames | 回應來源檔案中有多少frames。
NumFramesDown | 設定或傳回每張的圖片長度。33
NumFramesAcross | 設定或傳回來源圖片的寬度。
MouseEventsEnabled | 設定或傳回來源圖片的Mouse事件是否被處理。
PlayRate | 設定sprite控制項的播放速率，不論您在前進或後退時，都可以改變sprite控制項的播放速率。
PlayState34 | 回應play，paused或stopped三個狀態之一。
Repeat | 設定或傳回Sprite控制項應該跑的迴圈數。
SourceURL | 指定來源檔案位置。
Time | 傳回Sprite控制項已經播放過的時間。35
TimeInterval | 設定frame更新的時間以微秒表示。

程式19-6是利用不同角度的地球轉動圖形，做出一頁頁地球轉動的效果。程式19-6使用了earth.gif，裡面有21張不同角度的地球影像，圖19-4是部分的GIF圖檔影像。

圖 19-4 earth.gif 的部分影像，裡面還有更多的地球影像

每一張地球的影像都是Sprite控制項一個畫面。當所有影像依序播放時，就可以做出地球轉動的效果。我們在此將Repeat設為 -1，代表地球會一直轉動，圖19-5是最後的結果。

<HTML>
<HEAD>
<TITLE>Code Listing 19-6</TITLE>
</HEAD>
<BODY BGCOLOR="black">
<OBJECT ID="globe" STYLE="width:200;height:150"
  CLASSID="clsid:FD179533-D86E-11D0-89D6-00A0C90833E6">
  <PARAM NAME="NumFrames" VALUE="21">
  <PARAM NAME="NumFramesAcross" VALUE="1">
  <PARAM NAME="NumFramesDown" VALUE="21">
  <PARAM NAME="ColorKey" VALUE="255,0,255">
  <PARAM NAME="UseColorKey" VALUE="-1">
  <PARAM NAME="SourceURL" VALUE="earth.gif">
  <PARAM NAME="Repeat" VALUE="-1">
  <PARAM NAME="InitialFrame" VALUE="1">
</OBJECT><P>
<INPUT TYPE="button" VALUE="Play" onclick="globe.Play()">
<INPUT TYPE="button" VALUE="Pause" onclick="globe.Pause()">
<INPUT TYPE="button" VALUE="Stop" onclick="globe.Stop()">
<INPUT TYPE="button" VALUE="Frame" onclick="alert(globe.Frame)">
<INPUT TYPE="button" VALUE="Time" onclick="alert(globe.Time)">
</BODY>
</HTML>36
程式19-6

圖19-5　可利用螢幕上的控鈕來控制地球的旋轉

Play、Pause、Stop鈕分別會呼叫Sprite中對應的控制項。Frame及Time鈕將會顯示目前播放的畫面時間以及撥放的frame數字。

Sprite控制項不僅能用在簡單的動畫上，程式19-7用指定frome的方式，讓使用者按下按鈕時，能看到地球的不同區域，圖19-6就是顯示的結果。

<HTML>
<HEAD>
<TITLE>Code Listing 19-7</TITLE>
</HEAD>
<BODY BGCOLOR="black">
<OBJECT ID="globe" STYLE="width:200;height:150"
  CLASSID="clsid:FD179533-D86E-11D0-89D6-00A0C90833E6">
  <PARAM NAME="NumFrames" VALUE="21">
  <PARAM NAME="NumFramesAcross" VALUE="1">
  <PARAM NAME="NumFramesDown" VALUE="21">
  <PARAM NAME="ColorKey" VALUE="255,0,255">
  <PARAM NAME="UseColorKey" VALUE="-1">
  <PARAM NAME="SourceURL" VALUE="earth.gif">
  <PARAM NAME="InitialFrame" VALUE="1">
</OBJECT><P>
<INPUT TYPE="button" VALUE="South America" onclick="globe.FrameSeek(21)">
<INPUT TYPE="button" VALUE="Asia" onclick="globe.FrameSeek(12)">
<INPUT TYPE="button" VALUE="Africa" onclick="globe.FrameSeek(16)">
<INPUT TYPE="button" VALUE="North America" onclick="globe.FrameSeek(2)">
</BODY>
</HTML>
程式19-737

圖19-6　使用 Sprit 控制項讓使用者能操作圖片

當按鈕按下時, 就會呼叫Sprite控制項的FrameSeek方法，同時並傳遞一個引數給Sprite控制項, 這樣會讓Sprite控制項跳到指定的frame畫面，所以地球上的指定區域就會出現在畫面上。

除了FrameSeek外，Sprite控制項還支援其他DirectAnination控制項的方法， 例如：Play、Pause、Seek、Stop以及Add Time Marker。同時也支援一般常見的事件，例如：onclick、ondbclick、onframeseek、onmarker、marker、onseek及onstop事件....等等。onmediaload事件會在控制項及其中的圖形載入時觸發。我們前面已經說過，捕捉動作最好的方法，還是透過Script，而不是事件處理器。

本章所介紹的多媒體控制項可以在不增加網頁太多負擔的情況下, 增加許多媒體效果。Structured Graphics控制項可以讓你在網頁中加入可縮放的向量圖案。而Sequencer控制項可以讓你編排動作的順序，Path控制項可以幫你控制畫面上的物件移動路徑。Sprite控制項可以幫你建立以frame為基礎的動畫與圖片。

本書下一個部分將會介紹進階的網頁技巧, 包括有資料連結 (Data Binding) 及XML與跨瀏覽器的Script等等...。


實戰Dynamic HTML網站技術=>資料連結(Data Biding)

資料連結(Data Biding)
小
工
具 加入書架
加入書籤
上一章
下一章

一個內含在Microsoft Internet Explorer的資料連結技術，稱之為Data binding技術，此技術是一個十分有用且節省時間的技術，Data binding同時提供給網站開發者和使用者許多的優點，這些優點包括讓製作與更新網頁更容易、下載網頁更快速，且較不依賴遠端伺服器，會有這些優點是因為它允許網頁的資料可以保存在本地 (locally) 且與設定格式的HTML原始碼分離。

透過所有的資料來源物件 (Data Source objects; DSOs)，網頁變成了可以填入外部資料的一種樣本，而這些樣本供顯示或處理，在本章中，我們將討論data binding和DSO如何運作，然後我們會探討使用一個特定DSO ─表格式資料控制項 (Tabular Data Control) 的例子。這些例子展示如何透過簡單的Scripts，來使用到Data binding的強大功能。雖然Netscape Navigator不支援HTML元件直接連結資料，不過它支援一種DSO，此DSO即為JDBC (Java Data Connectivity) 的applet，稍後本章會討論。最後，我們會簡單瀏覽一下其他更進階的Data binding技術。

Data binding的優點

Data binding同時提供了一些實用的好處給網站開發人員和使用者，其中一個好處在於可以降低對於遠端伺服器更新和處理資料的依賴程度。為了讓您更容易瞭解，我們觀察一個可以列出藥草與其功效的網站實例，來檢視如何處理資料及使用Data binding之前，使用者如何存取資料。因為利用資料庫處理的網站已經越來越普遍了，所以我們假設所有的草本植物的資料都儲存在資料庫中。1

如果使用者想要看到在您網站上所有藥草常用名稱的排序列表，使用者通常需要透過HTML表單來提出要求。然後，伺服器從資料庫傳回所要求的資訊，要處理它需要使用一些伺服器端 (server-side) 的技術，例如：ASP(Acitve Server Pages)、CGI(Common Gateway Interface) 或ISAPI(Internet Server API) 之script語言，然後根據所需資訊建立一個網頁，接著將新建立HTML檔案傳送到使用者的瀏覽器中。

一般來說，任何使用者額外的要求需要很多趟傳送到伺服器端的處理程序。舉例來說，若使用者想要用同樣的藥草，不過是以植物學名稱來排序。使用者需要提出另外的要求且整個龐大的處理程序又要再來一次。這種耗時又沒效率的程序不只讓伺服器需要同時負擔數以百計或千計的要求 (端視網站受歡迎程度)，也讓本來擁擠的Internet增加負擔。

Data binding明顯地減輕了這種擁塞情況，這是因為它在使用者第一次要求時就直接且只傳送需要的資料，並且利用一個在網頁上的DSO來處理回應的要求， 另一個這種程序的優點在於網站開始者，可以依照需求來給予使用者控制多或少的下載資料。

舉例來說，開發者可以允許使用者，對於原始資料來做排序，篩選，或其他檢視上的改變，而並無需回傳伺服器 (除非需要的是一個完全不同的一組資料)。

您可能會預期開始下載一大堆資料可能會花費很多時間，然而，因為Internet Explorer提供非同步載入資料，那就是一旦有足夠的資料下載，它就開始顯示資料到網頁上，在所有資料可供操作之前，使用者就可以和網頁互動了。

資料來源物件(DSO)

資料來源物件實行了一個傳送資料給一個Web-based文件的標準化模型，DSO允許開發者決定下列事項：2

  • 資料如何被傳送 (例如：使用HTTP通訊協定)。
  • 資料如何被處理 (例如：排序和篩選)。
  • 資料是否被更新，如果是要利用何種技術來更新。
  • 資料如何被儲存 (例如：一般純文字或SQL)。
  • 一個利用Scripts來取得資料的物件模型。

Internet Explorer提供許多種DSO；不過較高明的程式設計師可能會想要設定它們自己的DSO。DSO可使用例如Java或C++ 來撰寫。一旦撰寫完成，這個DSO便可直接透過一般的Internet Explorer介面來操作。DSO的資料可以透過網頁上的script來處理，或可以自動地連結至Internet Explorer所支援，且稱為data binding extensions的特定HTML標籤。

幸運的是，您不需撰寫您自己的DSO就可以享受到利用Internet Explorer 連結資料的優點。可使用在Internet Explorer中的DSOs有：遠端資料服務 (Remote Data Service；RDS)，表格資料控制項 (Tabular Data Control；TDC) 和XML DSO (Extensible Markup Language；XML下一章會談到)，每個DSO都有其優缺點。3

遠端資料服務讓使用者可以直接從網頁上來讀取，處理和更新資料，這些資料是透過OLE DB Provider (稍後會解釋)，包括相容ODBC的資料庫 (ODBC代表Open Database connectivity，正如名稱所提示的，是一個允許存取資料庫的介面)，如此容易取得資料的特性，在分工合作的LAN或WAN中，分享一個集中式資料庫的情況下，對於在不同位置上工作的人來說很重要。

JDBC applet是相容於Java Beans且支援目前的Netscape Navigator的版本，也支援Internet Explorer 4和5，Netscape並不支援像Internet Explorer一樣可以自動地將資料連結到HTML文件中，不過資料還是可以透過script來取得。

表格資料控制項 (TDC) 使用一個簡單的文字檔做資料來源，它是最容易在客戶端實行且使用的。它最大的缺點在於它並不直接支援在server端更新資料，本章大部分的例子我們將使用TDC。

DSOs可被撰寫來執行許多資料庫函式。例如表格資料控制項可以利用 script和Dynamic HTML來顯示排序及篩選資料，這種功能可以使用，因為DSO元件允許資料和HTML程式碼分離，正如我們早先敘述的，DSO/data binding模型將網頁視為一個樣本，此樣本充滿由DSO所指定的資料。最佳的Microsoft資料存取技術的線上程式設計師參考手冊可以在 microsoft.com/data 找到。

如何將資料從DSO送至網頁4

為了讓一個DSO可以運作，它必須出現在網頁上 (通常是以一個ActiveX控制項或Java Applet的形式)。一旦DSO在網頁上，其它的兩個元件－顯示資料元件 (data consumers) 和資料連結元件 (Binding agents)。此兩個元件用來將資料帶到網頁當中。

可顯示由DSO所提供資料的網頁元件被稱為顯示資料元件 (data consumers)。這些元件可以是標準的HTML標籤，例如SPAN，DIV，或TABLE或外部物件，例如：ActiveX控制項或Java Applets。使用顯示資料元件必須按照所提供的資料種類，而這些種類可以是單一值 (Single-Value) 的資料或表格式 (Tabular )的資料，舉例來說，DIV元件可以使用來顯示一個由資料來源提供的目前紀錄值。相對的TABLE元件可以從資料來源中取得整組資料紀錄。

Internet Explorer支援許多HTML屬性用於顯示資料元件做資料連結時：

  • DATASRC屬性利用物件的ID來辨識DSO物件。
  • DATAFLD屬性可指定由DSO所提供的欄位 (資料欄位)。
  • DATAFORMATS屬性可設定資料如何被格式化。舉例來說，是HTML或一般純文字。
  • DATAPAGESIZE屬性設定同一時間可以使用的紀錄 (針對表格而言)。5

資料連結元件(Binding agents) 也是Internet Explorer內建的元件。它們完全在背景運作，用來辨別與維護DSO所提供的資料，當一個網頁被載入時，資料連結元件會辨別所有網頁中的DSO和顯示資料元件。然後維持DSO與顯示資料元件之間的資料同步 (synchronization of data)，且指向兩個方向的資料傳輸路徑，從DSO到顯示資料元件，若網頁上的資料改變時，則從顯示資料元件到DSO。現在您已經有些資料連結的背景知識了，因此我們就來實際做一些資料連結的例子。

表格資料控制項(Tabular Data Control)

表格資料控制項(Tabular Data Control;TDC) 是一個內建的ActiveX控制項。這種DSO並沒有使用標準資料庫，而是使用有分隔符號的文字檔來當作資料來源。有分隔符號的文字檔只是表示文字檔中的資料項目以常見的符號分隔。舉例來說，Dill|Anethum graveolens|Culinary and Medicinal這段文字，每個資料項目被管線字元 (pipe character; | )所分隔。另一個常見的分隔符號文字檔類型被稱之為Comma-Seperated-Values檔案，或簡稱CSV。

我們來詳細看看更多的有關這種資料的實例。

Angelica | Angelica archangelica | Culinary6
Basil | Ocimum basilicum | Culinary and Medicinal
Basil，Cinnamon | Ocimum basilicum | Culinary and Medicinal
Basil，Holly7 | Ocimum basilicum | Culinary and Medicinal
Basil，Spicy Globe | Ocimum basilicum | Culinary and Medicinal

在表格式文字 (tabular text) 的每一項都是一個欄位 (field)，水平的一組欄位我們稱之為一個列 (row)。如果我們使用管線 (Pipe) 字元當作欄位分隔符號，換行字元當作列分隔符號，如此來將這個資料表轉換成一個有分隔符號的文字檔案，產生的結果，如下所示：

Angelica|Angelica archangelica|Culinary
Basil|Ocimum basilicum|Culinary and Medicinal
Basil，Cinnamon|Ocimum basilicum|Culinary and Medicinal
Basil，Holly|Ocimum basilicum|Culinary and Medicinal
Basil，Spicy Globe|Ocimum basilicum|Culinary and Medicinal8

注意每個資料表的水平列都變成了文字檔中的一行。您所選擇用來設定分隔符號的不同字元，當然必須依據您在欄位中放了甚麼資料。舉例來說，如果您想要一個資料項目包含多行文字，您可能就不能使用換行字元當作分隔符號。一個文字限定符號 (text qualifier；稍後會談到) 是一種選用的分隔符號，此符號有助於整個欄位被視為一個資料項目。

將資料連結一個單獨元件

儘管名稱裡面有 "表格"，表格資料控制項也支援單一值資料，和表格資料一樣。我們第一個例子展示如何使用TDC來連結資料到單一值的HTML元件中。在這個例子中，我們將會使用上面草藥的資料來填入一個SPAN元件。資料檔herbs.txt是一個含有分隔符號的文字檔案，此檔案儲存有關草藥的資料。

在這個檔案中，我們使用兩個分隔符號：一個文字限定符號 (驚嘆號 !) 和一個欄位分隔符號 (管線字元 |)。文字限定符號指定每塊文字的邊界，允許我們可以包含一個在其他地方當作分隔符號的項目 (請參考下面"了解分隔符號(Delimiters)" 的說明)，欄位分隔符號在一個紀錄中指定每個欄位之界限。

了解分隔符號(Delimiters)

乍看之下，似乎文字限定符號和欄位分隔符號的用途相同，但是事實上它們有很大的不同。若同時使用這兩種分隔符號，設計者可以幾乎完全自由地使用任何它們想要的字元，包括在資料檔中當作分隔符號的字元。舉例來說，假設一個資料檔案使用井字符號 (#) 當作欄位分隔符號，及使用驚嘆號 (!) 當作一個文字限定符號，如果您需要在一個文字欄位包含一個井字符號，您應該將它包含在一個文字限定符號內，且它會被當成文字來顯示，而非將它編譯成一個欄位分隔符號。因此，資料 #!This is the pound # sign! # 會被當作包含This is the pound # sign這段文字的單一資料。

我們的TDC例子都是使用herbs.txt檔案，此檔案為書附光碟中的chap20\herbs.txt。這裡列的是herbs.txt開頭前15行資料。請注意第一列 (稱作標頭列，row header) 和之下的其它列的資料不同。9

common|botan|usage
!Angelica!|!Angelica archangelica!|!Culinary!
!Basil!|!Ocimum basilicum!|!Culinary and Medicinal!
!Basil，Cinnamon!|!Ocimum basilicum!|!Culinary and Medicinal!
!Basil，Holly!|!Ocimum basilicum!|!Culinary and Medicinal!
!Basil，Spicy Globe!|!Ocimum basilicum!|!Culinary and Medicinal!
!Bay!|!Laurus nobilis!|!Culinary!
!Laurel，Sweet!|!Laurus nobilis!|!Culinary!
!Borage!|!Borago officinalis!|!Culinary and Medicinal!
!Burnet!|!Sanguisorba minor!|!Culinary!
!Catnip!|!Nepeta cataria!|!Culinary!
!Catmint!|!Nepeta cataria!|!Culinary!
!Chamomile!|!Chamaemelum nobile!|!Medicinal!
!Chervil!|!Anthriscus cerefolium!|!Culinary!
!Chives!|!Allium schoenoprasum!|!Culinary and Medicinal!

現在您已經看到herbs.txt檔案，我們來看看我們第一個基本例子的HTML原始碼，如程式20-1所示。圖20-1展示執行此程式碼的結果。注意即使Angelica這個字並沒有出現在HTML原始碼中，不過它還是顯示在螢幕中，因為這是從資料檔讀取而來的。

<HTML>
<HEAD>
<TITLE>Code Listing 20-1</TITLE>
<OBJECT ID="herbTDC" CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83">
  <PARAM NAME="TextQualifier" VALUE="!">
  <PARAM NAME="FieldDelim" VALUE="|">
  <PARAM NAME="DataURL" VALUE="herbs.txt">
  <PARAM NAME="UseHeader" VALUE="true">
</OBJECT>
</HEAD>
<BODY>
<B>Common Name-</B><SPAN DATASRC="#herbTDC" DATAFLD="common"></SPAN>
</BODY>
</HTML>
程式20-1

圖20-1　一個單獨的HTML元件連結一個資料檔案

網頁中的OBJECT元件設定TDC為我們的DSO，且指定一大堆引數，包括設定herbs.txt為目的資料檔。herb資料檔的第一欄以草藥常見名稱來作列表。這個欄位連結至SPAN元件。注意在程式20-1中的 <SPAN> 標籤包含DATASRC屬性，它利用ID來辨別資料來源 (DSO)。也要注意一下資料來源ID ，在物件名稱前面，需要一個井字號 (#)。DATAFLD屬性決定哪一個資料欄位與SPAN元件結合，在這個例子中，欄位名稱為common。10

DSO知道在資料庫中的欄位名稱，因為它們被定義在資料檔案中。欄位名稱會出現在herbs.txt的第一行中，而此行只有使用欄位分隔符號而沒有文字限定符號。因為在 <PARAM> 標籤中我們設定UserHeader屬性為true，所以DSO知道要使用第一行來當欄位名稱。若您沒有設定欄位名稱，且您的檔案只包含資料，您可以利用欄位編號來參考到欄位。例如，此時就不能使用DATAFLD="common"，我們可能要使用DATAFLD="Column1"。記得為了讓欄位號碼也能順利運作，UserHeader屬性不能設定成true。

當然，我們的資料檔不只是包含藥草的一般名稱，每個紀錄也包含了藥草的植物學名稱和一些用途上的相關資訊，這裡展示了許多不同的藥草。程式20-2展示如何顯示這些資訊，如何在資料庫裡移動前後紀錄，及如何透過script來控制資料。

<HTML>
<HEAD>
<TITLE>Code Listing 20-2</TITLE>
<OBJECT ID="herbTDC" CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83">
  <PARAM NAME="TextQualifier" VALUE="!">
  <PARAM NAME="FieldDelim" VALUE="|">
  <PARAM NAME="DataURL" VALUE="herbs.txt">
  <PARAM NAME="UseHeader" VALUE="true">
</OBJECT>

<SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="onload">
  herbRS=herbTDC.recordset
  herbRS.MoveFirst()
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
function displayInfo(){
  CurPos=("Record "+herbRS.AbsolutePosition+" of "+herbRS.RecordCount)
  CurVal1=("\nField 1=" + herbRS.fields('common') )
  CurVal2=("\nField 2=" + herbRS.fields('botan') )
  CurVal3=("\nField 3=" + herbRS.fields('usage') )
  alert(CurPos+CurVal1+CurVal2+CurVal3)
}
</SCRIPT>
</HEAD>
<BODY>
<INPUT TYPE="button" VALUE="<<" onclick="herbRS.MoveFirst()">
<INPUT TYPE="button" VALUE="<"
  onclick="herbRS.MovePrevious();if(herbRS.BOF)herbRS.MoveFirst()">
<INPUT TYPE="button" VALUE="Display Info" onclick="displayInfo()">
<INPUT TYPE="button" VALUE=">"
  onclick="herbRS.MoveNext();if(herbRS.EOF)herbRS.MoveLast()">
<INPUT TYPE="button" VALUE=">>" onclick="herbRS.MoveLast()">
<P><B>Common Name-</B><SPAN DATASRC="#herbTDC" DATAFLD="common"></SPAN>
<P><B>Botanical Name-</B><SPAN DATASRC="#herbTDC" DATAFLD="botan"></SPAN>
<P><B>Usage-</B><SPAN DATASRC="#herbTDC" DATAFLD="usage"></SPAN>
</BODY>
</HTML>
程式20-2

圖20-2　顯示紀錄中所有的欄位，且讓您移動與檢視所加入的資料

為了顯示每個藥草的資料，在原來的SPAN元件之下加入了更多的SPAN元件，且連結到資料庫中適合的資料欄位。每次TDC移動到新紀錄時，由於每個SPAN元件連結到不同的資料欄位，資料欄位會分別顯示在其連結到的SPAN元件中。11

當網頁載入時，就會執行script來設定herbRS變數，而去參考herbTDC物件的recordset子物件。所有DSO物件都支援recordset物件，它可以用來瀏覽整個資料和插入、刪除和更新資料。

在網頁的上方，四個方向按鈕，按鈕字元為 <<、<、>和 >> 讓使用者來瀏覽整個資料檔的藥草名稱。要看看哪個按鈕被按下，就會呼叫相對應recordset物件的Movefirst、MovePrevious、MoveNext或MoveLast函式，且目前的顯示資料會跟著改變。您也許也有發覺在程式20-2中在 < 和 > 按鈕處有個額外的程式碼。這段程式測試recordset物件的BOF(Beginning Of File檔案開頭)和EOF(End Of File檔案結尾) 屬性，讓我們知道我們在資料檔何處，且不會移動資料到recordset的界線之外。

Display Info按鈕會執行displayinfo函式。這個函式包含目前在recordset的位置資料且會將其顯示在一個警告窗中。AbsolutePosition屬性包含了在recordset的目前位置。這個屬性也可以設定特定數值，直接跳至該資料列。RecordCount屬性包含資料庫所有的資料列數目。recordset物件的fields方法，傳回目前紀錄的一個特定欄位值。

支援單一值資料連結的HTML元件

除了SPAN元件外，Internet Explorer也支援許多常用的HTML元件使用資料連結技術。表格20-1列出支援資料連結的HTML元件，並敘述哪些方面的元件被連結，且說明此元件是否支援更新資料。所有在此處列的資料都支援單一值資料連結。除了TABLE元件 (沒有列在此表，不過會在下一段討論) 支援表格式資料。

表20-1　支援單一值資料連結的HTML元件
HTML元件12 | DSO連結到 | 支援更新
A | HREF | 否
APPLET | <PARAM>中的屬性值13 | 是
BUTTON | innerText，innerHTML | 否
DIV | innerText，innerHTML | 否14
FRAME | SRC | 否
IFRAME | SRC | 否
IMG15 | SRC | 否
INPUT TYPE=checkbox | CHECKED | 是
INPUT TYPE=hidden | VALUE16 | 是
INPUT TYPE=label | VALUE | 是
INPUT TYPE=password | VALUE | 是17
INPUT TYPE=radio | CHECKED | 是
INPUT TYPE=text | VALUE | 是
LABEL18 | innerText，innerHTML | 否
MARQUEE | innerText，innerHTML | 否
SELECT | 目前選定的OPTION的文字屬性值19 | 是
SPAN | innerText，innerHTML | 否
TEXTAREA | VALUE | 是20

連結資料到一個表格元件

在前一段中，您看到如何在單一HTML元件中顯示資料，且讓設定者和使用者有更多選擇，並對資料有更好的控制。不過如果我們要顯示一整個recordset呢? 有兩個累人的方法，其一為建立一個資料連結元件包含每個資料欄位與資料列， 其二為利用一個script直接在網頁上建立所有需要的元件。幸運地，這裡有更簡單的方法。使用HTML <TABLE> 標籤，您只需透過DSO花很少的功夫，就可以顯示所有欄位資料。

程式20-3展示只是要建立一個5筆藥草紀錄的資料表格，此表格沒有使用資料連結而直接將資料輸入HTML檔案中。圖20-3顯示瀏覽結果。

<HTML>
<HEAD>
<TITLE>Code Listing 20-3</TITLE>
</HEAD>
<BODY>
<TABLE BORDER="1" CELLSPACING="0">
  <THEAD>
    <TR>
      <TD><B>Common Name</B></TD>
      <TD><B>Botanical Name</B></TD>
      <TD><B>Usage</B></TD>
    </TR>
  </THEAD>
    <TR>
      <TD>Angelica</TD>
      <TD>Angelica archangelica</TD>
      <TD>Culinary</TD>
    </TR>
    <TR>
      <TD>Basil</TD>
      <TD>Ocimum basilicum</TD>
      <TD>Culinary and Medicinal</TD>
    </TR>
    <TR>
      <TD>Basil，Cinnamon</TD>
      <TD>Ocimum basilicum</TD>
      <TD>Culinary and Medicinal</TD>
    </TR>
    <TR>
      <TD>Basil，Holly</TD>
      <TD>Ocimum basilicum</TD>
      <TD>Culinary and Medicinal</TD>
    </TR>
    <TR>
      <TD>Basil，Spicy Globe</TD>
      <TD>Ocimum basilicum</TD>
      <TD>Culinary and Medicinal</TD>
    </TR>
  </TABLE>
</BODY>
</HTML>
程式20-3

圖20-3　沒有使用資料連結，而直接用資料來建構的表格21

資料連結減少了建立一個資料表格所需要撰寫的程式碼，所以簡化了程式的處理過程。利用資料連結技術，所有資料檔中的60筆資料，可以利用一小段程式就可完成，這小段程式，比剛剛看到將所有5筆資料都直接鍵入到原始碼的網頁還要精簡。程式20-4使用了資料連結。圖20-4展示執行此網頁時結果表格。您會注意到除了原始碼的大小不同外，兩者所顯示的基本上相同。

<HTML>
<HEAD>
<TITLE>Code Listing 20-4</TITLE>
<OBJECT ID="herbTDC" CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83">
  <PARAM NAME="TextQualifier" VALUE="!">
  <PARAM NAME="FieldDelim" VALUE="|">
  <PARAM NAME="DataURL" VALUE="herbs.txt">
  <PARAM NAME="UseHeader" VALUE="true">
</OBJECT>
</HEAD>
<BODY>
<TABLE DATASRC="#herbTDC" BORDER="1" CELLSPACING="0">
  <THEAD>
    <TR>
      <TD><B>Common Name</B></TD>
      <TD><B>Botanical Name</B></TD>
      <TD><B>Usage</B></TD>
    </TR>
  </THEAD>
  <TR>
    <TD><SPAN DATAFLD="common"></SPAN></TD>
    <TD><SPAN DATAFLD="botan"></SPAN></TD>
    <TD><SPAN DATAFLD="usage"></SPAN></TD>
  </TR>
</TABLE>
</BODY>
</HTML>
程式20-4

圖20-4　一個利用資料連結所建構的表格

如果您想要更新430頁(沒有使用資料連結) 程式20-3所建立的表格，您需要改變表格中所有儲存格的HTML原始碼。若是修改程式20-3 (使用資料連結) 的表格，您只需修改資料檔案即可。舉例來說，一個修改過的資料檔可能包含非英語 (如中文) 的藥草資料，只要修改資料檔將資料變成中文，如此可避免翻譯者去處理HTML原始碼。

處理資料(Manipulating Data)22

資料一旦放在網頁中，資料就可以用許多方法來處理，例如：資料可排序、篩選、更改、新增和刪除。

排序與篩選

TDC是一個同時支援排序和篩選操作的DSO，正如下所示，程式20-5展示我們如何增強的herb網頁來允許使用者將資料列表依照一般名稱、植物名稱與用途來排序。此外，還可以依據特定用途來篩選整個資料表。當下拉式選單的選項改變時，相對於此選項的動作就會執行，圖20-5為表格以一般名稱排序且篩選出，顯示用途同時為食用與藥用的藥草。

<HTML>
<HEAD>
<TITLE>Code Listing 20-5</TITLE>
<OBJECT ID="herbTDC" CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83">
  <PARAM NAME="TextQualifier" VALUE="!">
  <PARAM NAME="FieldDelim" VALUE="|">
  <PARAM NAME="DataURL" VALUE="herbs.txt">
  <PARAM NAME="UseHeader" VALUE="true">
</OBJECT>
</HEAD>
<BODY>
<B>Sort by:</B>
<SELECT onchange="herbTDC.Sort=('+'+this.value); herbTDC.Reset()">
  <OPTION VALUE="">None</OPTION>
  <OPTION VALUE="common">Common Name</OPTION>
  <OPTION VALUE="botan">Botanical Name</OPTION>
  <OPTION VALUE="usage">Usage</OPTION>
</SELECT>
<B>Filter by:</B>
<SELECT onchange="herbTDC.Filter=('usage='+this.value); herbTDC.Reset()">
  <OPTION VALUE="">None</OPTION>
  <OPTION VALUE="Culinary">Culinary</OPTION>
  <OPTION VALUE="Medicinal">Medicinal</OPTION>
  <OPTION VALUE="Culinary and Medicinal">Culinary and Medicinal</OPTION>
</SELECT>
<P>
<TABLE DATASRC="#herbTDC">
  <THEAD>
    <TR>
      <TD><B>Common Name</B></TD>
      <TD><B>Botanical Name</B></TD>
      <TD><B>Usage</B></TD>
    </TR>
  </THEAD>
    <TR>
      <TD><SPAN DATAFLD="common"></SPAN></TD>
      <TD><SPAN DATAFLD="botan"></SPAN></TD>
      <TD><SPAN DATAFLD="usage"></SPAN></TD>
    </TR>
</TABLE>
</BODY>
</HTML>
程式20-5

在程式20-5中，排序與篩選引數分別放在2個SELECT元件中，當使用者選擇其中一個下拉列視窗，則先會設定TDC的Sort或Filter屬性，然後呼叫Reset方法來重新載入由Sort和Filter屬性所新設定的資料。

Sort屬性可以被設定由單一欄位或多欄位排序，且可設定遞增或遞減排序，若想以common欄位來遞減排序，您可設定herbTDC.sort="+common" 及使用herbTDC.Reset() 來套用此排序字串。若想以usage遞增且common遞減排序，您可設定為herbTDC.sort="+usage;-common"。23

Filter屬性允許顯示資料限定在所有資料的一個特定子集合中，一個簡單的filter例子為herbTDC.Filter="usage=Culinary"，它只會顯示usage欄的值為Culinary的項目，一個更為複雜的filter例子為herbTDC.Filter="usage<>Culinary & (common=Oregano | common>Sage)"，它只會顯示usage欄位不等於Culinary且common欄位，包含Oregano或Common欄位值的第一個字母在Sage之後，有關複雜的Filtering資料，可在SBN Workshop網站和書附光碟中找到，請觀看CD中 \WORKSHOP\ DATABASE\TDC\REFERENCE\FILTER\HTM。若想要取得線上版本，請連至MSDN線上資源網站 msdn.microsoft.com/resources/schrumdhtml.htm ，或開啟書附光碟中的MSDN_OL.htm，選擇Filter Property。

圖20-5　同樣一組紀錄被排序和篩選後的情況

新增、修改和刪除資料

一些DSO允許使用者透過從記憶體中的動態Recordset中，改變一個欄位值或新增移除資料，來修改一個Recordset。TDC是此種DSO的其中一種 (雖然不允許改變來源資料檔)。Addnew語法如下所示：24

dsoID.recordset.AddNew()

一旦使用Addnew方法，空白資料錄(record) 會被加在Recordset的最後，空白欄可以透過script或支援Recordset更新的HTML元件(參考表格20-10) 來設定。

dsoID.recordset.fields('column name')="new value"

我們將這個技巧套用在前一個程式中，如下所示：

herbRS.AddNew();
herbRS.fields('common')='Dhaction';
herbRS.fields('botan')='Dynamicia HTMLicus in Actionious';
herbRS.fields('usage')='Creating Cool Web Pages'"

Delete方法的運作方式和Addnew相似，使用下列語法：

dsoID.recordset.Delete()25

這個技巧可從recordset刪除掉動態資料錄。在程式20-6有展示如何新增與改變一個recordset 。

雖然TDC並不支援修改遠端來源的原始資料，其他DSO，例如RDS就包含這項功能。有關RDS和DSO的資訊可以在SBN Workshop網站與書附光碟。請參考光碟中DHTML，HTML，& CSS/Data Binding/Adding a Data Source Object to a Page。若要取得線上版本，請連至MSDN線上資源網站 msdn.microsoft.com/resources/schrumdhtml.htm ，或開啟書附光碟中的MSDN_OL.htm，選擇Adding a DSO。

先前所講的the Microsoft Universal Data Access網站 ( microsoft.com/data ) 也提供有用的技術資訊，和有關DSO的進一步參考資料與一般資料存取資訊。26

資料事件

有一些可以控制網頁上資料連結 (Data bound)元件及與之互動的工具能夠使用。資料連結元件是一種HTML元件，這種HTML元件都是可連結到包含資料的DSO中。使用標準的物件模型事件，網頁開發者可以利用scripts，來處理當資料連結元件修改資料時該如何反應。

動態網頁Data Binding事件

Internet Explorer支援許多資料連結事件，有些是應用在DSO中，有些是應用在資料連結元件中，且有一個是只有應用在windows物件的。下面列出最常用的資料連結事件：

Data Binding事件 | 事件物件
onbeforedate27 | Data bound element
onafterdate | Data bound element
onerrorupdate | Data bound element
onbeforeunload | window物件28
onrowenter | DSO
onrowexit | DSO
ondataavaiable | DSO
ondatasetcomplete29 | DSO
ondatasetchanged | DSO
onreadystatechange | DSO

在程式20-6中所列的script程式碼使用ondatasetcomplete和ondatasetchanged事件。當資料完全下載時，會發生ondatasetcomplete事件。它可以用來確定有沒有資料尚未下載。不論是用排序或篩選來改變操作資料，就會發生ondatasetchanged事件。注意的是當網頁完全下載，且每次執行一個新的排序操作，則此兩個事件都會發生。

<HTML>
<HEAD>
<TITLE>Code Listing 20-6</TITLE>
<OBJECT ID="herbTDC" CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83">
  <PARAM NAME="TextQualifier" VALUE="!">
  <PARAM NAME="FieldDelim" VALUE="|">
  <PARAM NAME="DataURL" VALUE="herbs.txt">
  <PARAM NAME="UseHeader" VALUE="true">
</OBJECT>
<SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="onload">
  herbRS=herbTDC.recordset;
  herbRS.MoveFirst()
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript" FOR="herbTDC" EVENT="ondatasetcomplete">
  alert("The data is fully loaded.")
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript" FOR="herbTDC" EVENT="ondatasetchanged">
  alert("The working data set has changed.")
</SCRIPT>
</HEAD>
<BODY>
<INPUT TYPE="button" VALUE="Add Record"
  onclick="herbRS.AddNew();
           herbRS.fields('common')='Dhaction';
           herbRS.fields('botan')='Dynamicia HTMLicus in Actionious';
           herbRS.fields('usage')='Creating Cool Web Pages'">
<B>Sort by:</B>
<SELECT onchange="herbTDC.Sort=('+'+this.value); herbTDC.Reset()">
  <OPTION VALUE="">None</OPTION>
  <OPTION VALUE="common">Common Name</OPTION>
  <OPTION VALUE="botan">Botanical Name</OPTION>
  <OPTION VALUE="usage">Usage</OPTION>
</SELECT>
<TABLE DATASRC="#herbTDC">
  <THEAD STYLE="font-weight: bold">
    <TR><TD>Common Name</TD><TD>Botanical Name</TD><TD>Usage</TD></TR>
  </THEAD>
    <TR>
      <TD><SPAN DATAFLD="common"></SPAN></TD>
      <TD><SPAN DATAFLD="botan"></SPAN></TD>
      <TD><SPAN DATAFLD="usage"></SPAN></TD>
    </TR>
</TABLE>
</BODY>
</HTML>30
程式20-6

額外取得資料的方法

其實還有許多其他的資料來源。我們先前使用的資料是儲存在純文字檔中，不過，我們經常會將資料放在線上的資料庫中。許多DSO例如RDS和JDBC可以直接存取這些線上資料庫。您也可以使用許多伺服器端 (Server-Side) 的技術來存取資料。Active Server Pages (ASP) 技術 (Microsoft Windows NT Server-Internet Information Services的一部份) 就支援直接連接資料庫，例如連結至Microsoft SQL Server。程式20-7包含此種網頁的一個例子。注意這個網頁不能直接在CD上使用。它必須在一個已經適當設定的伺服器上執行。

<%@ LANGUAGE="JScript"%>
<HTML>
<HEAD>
<TITLE>Code Listing 20-7</TITLE>
<%
Conn = Server.CreateObject("ADODB.Connection")
Conn.Open("DSN"，"id"，"password")
rsFiles=Conn.execute("SELECT FName，LName FROM NameTbl WHERE Reg=1")
rsFiles.MoveFirst()
%>
</HEAD>
<BODY>
<TABLE BORDER="1">
  <THEAD>
  <TR><TD>First Name</TD><TD>Last Name</TD></TR>
  </THEAD>
<%
while (!rsFiles.EOF){
  %>
  <TR><TD><%=rsFiles(0)%></TD><TD><%=rsFiles(1)%></TD></TR>
  <%
  rsFiles.MoveNext()
}
Conn.Close()
%>
</TABLE>
</BODY>
</HTML>
程式20-7

大部分程式20-7的內容都非本書範圍，所以這邊簡單帶過就好，Active Server Pages讓您將伺服器端的script和客戶端的網頁結合。<% 和 %> 字元是區別伺服端script程式的開始和結束。伺服器端script的第一行提醒伺服器此ASP網頁使用JScript。接著伺服器端script的區塊建立一個連接物件 (Connection object)，且開啟一個資料庫的連接，此處的DSN是指資料庫 (可在伺服器端控制台中的ODBC設定找到) 的Data Source Name ，id是想使用資料的使用者， password是用來存取資料所設定的密碼。rsFiles recordset利用標準的SQL詢問來建立的，詢問在NameTbl表格中所有recordsets的FName和LName欄位，且Reg欄位設定成1。然後recordset會被設定為第一個資料錄。

開始的表格是用於客戶端網頁的，接著下一段開始就是伺服器端的script了。這個迴圈在recordset中巡行所有的紀錄，每次在網頁中撰寫一行HTML原始碼，此段原始碼包含一個有第一欄 (First Name) 和第二欄 (Last Name)的表格列，每個紀錄都有它們的儲存格。<%=variableName%> 會將variableName的內容顯示在網頁上。當迴圈結束後，會關閉與資料庫的連接來減低伺服器端的負荷。最後，關閉表格與網頁其他部分。這個ASP將會從資料庫傳回一個有first name和last name的表格。31

額外使用Data binding的方法

現在您知道資料連結如何運作了，我們將提供一些實務上的想法，讓您知道如何開始使用這項功能。

  • 一個被翻譯成不同語言的網站 不論文字是否需要在網站上使用，您可以將它以資料連結元件代替。然後您可以從一個外部資料來源取得所有的文字，且針對每一種語言使用不同的資料來源。
  • 一個公司的資料庫之前端 透過公司上網的使用者，可以經由公司的Intranet上的一個網頁來取得資料庫的資料
  • 一個線上商店32 所有產品資訊可以儲存並維護在資料庫中，且顯示在網站上。顧客可以依照價錢，目前庫存量，或其他設定條件，來顯示想要的資料。客戶資訊可以送至一個客戶資料庫中，在網站上使用資料連結控制項。
  • 一個參考資料網站 使用資料連結控制項可將參考資料庫連結到網頁中。在下載資料完畢後，使用者可以搜尋資料庫且修改資料的顯示。SBN Workshop有很多地方就是這做出來的，舉例來說，在書附光碟中，參考看看在 \WORKSHOP\AUTHOR\DATABIND\OBJMODEL.HTM中第一個找到的表格。

資料連結提供一個強大與有彈性的方式，在網頁文件中處理外部資料。使用資料連結和一個資料來源物件，您可以讓使用者使用多種方式來觀看資料，排序與篩選資料，和新增刪除資料。使用Internet Explorer的資料連結技術，您可用網頁為基礎 (Web-based) 的平台，來建立超強的資料庫驅動應用程式。


實戰Dynamic HTML網站技術=>延伸式標示語言 XML

延伸式標示語言 XML
小
工
具 加入書架
加入書籤
上一章
下一章

延伸標示語言 (eXtensible Markup Language;XML) 的出現是為了要彌補HTML的不足，而非取代HTML。基本上，XML是一種描述結構化資料的方法，不過和HTML文件不同的地方在於：XML文件並不包含任何描述文件該如何顯示的資訊，它只包含了有組織及描述性的構成資料。XML之所以能運用在各種應用上，是因為它只是一種資料格式而已。舉例來說，一個利用XML撰寫成的股市資訊文件，可以用瀏覽器來瀏覽，也可以匯入資料庫當作資料表單，甚至還可直接用文字編輯器來檢視。這種可延展的特性在某種程度上是做得到的，因為在XML文件中，資料的顯示方式並沒有特定的規則，且XML文件只是一個結構化的格式資料而已。本章將先從XML的背景及基本觀念講起，然後再探討如何撰寫XML文件，以及MS Internet Explorer是如何將XML整合到網頁上的。另外需要提醒的是，目前Netscape Navigator並沒有像Internet Explorer一樣提供對XML的支援。

XML的背景

HTML與XML都是由標準通用標示語言 (Standard Generalized Markup Language，簡稱SGML) 發展而來的。SGML是一種涵蓋範圍很廣的語言，它可以用來產生複雜資料系統 （或應用） 的製作方式，並且定義了資料描述及顯示規則。基本上，HTML是SGML的一個應用；但XML則是SGML的一個子集，其設計目的是為了提供一個簡單、可使網頁最佳化的資料呈現方式，因為使用這種方式比直接使用完善但複雜的SGML要來得容易多了。

XML的衍生規格1

XML在設計當初就有將Web考慮在內，而且提供了SGML所沒有的好處。瀏覽器可以利用XML搭配HTML來做資料的顯示與呈現。而為了支援XML在Web上的傳遞，目前還有兩種XML的相關規格被制定出來。

其中一種規格是「延伸連結語言」 (eXtensible Linking Language簡稱XLL)，這種規格描述的是一種超連結架構，用來同時支援傳統的HTML超連結及更進階的延伸超連結，其中後者可以讓單一連結指向多個不同的連結資源。雖然SGML也可以定義超連結機制，不過在SGML的原始規格中並沒有提到。

另一種規格是「延伸樣式語言」 (eXtensible Stylesheet Language簡稱XSL)，這種規格可以提供對XML樣式表架構的支援，這也是SGML規格中沒有涵蓋的部份。樣式表允許設計者建立樣式範本 (例如粗體、斜體等) 或樣式組合，當XML文件顯示時，即可將樣式範本或組合套用到各種XML元件 (Element)上。

簡單來說，XML擁有SGML百分之八十的功能，但其複雜度卻只有SGML的百分之二十。基本上，擁有一種簡單且通用的資料描述方法是十分有用的。舉例來說，由於XML擁有中立的資料交換格式，因此許多不同類型的系統都可以存取其資料。舉例來說，就我們所知，很多老舊的電腦系統是用各種不同的格式來儲存資料的，但是現在已經有一些系統轉換程式，可以讓很多舊系統可以讀取或輸出XML格式的資料。所以，在某個舊系統中用XML製成的資料檔案可以輕易地輸出到其他舊系統上、或發表成Web網頁、或輸出到其它支援XML的應用程式中。也就是說，XML可以當作是一個中介的資料格式，讓原本不相容的系統可以互相交換資料。

XML是一種資料

如果HTML是為了「顯示」資訊，那麼，XML就是為了「描述」資訊。XML是一個可以讓資料結構化並描述資料的標準語言，且可以讓不同的應用程式所瞭解。XML最大的威力就是它可以將使用者介面與資料分開。我們來看一個簡單的XML文件 (在隨書光碟中的資料夾中 /chap21/email.xml)，以瞭解XML是如何運作的：

<?xml version="1.0"?>
<EMAIL>
  <TO>Bill_Pardi@hotmail.com</TO>
  <FROM>Eric_Schurman@hotmail.com</FROM>
  <CC>DHTML_in_Action@hotmail.com</CC>
  <SUBJECT>Basic email</SUBJECT>
  <BODY>This is an XML-based email.</BODY>
</EMAIL>2

這個例子必須注意的重點是，在文件中並沒有描述如何顯示此份文件。換句話說，就是沒有包含樣式的資訊 (如粗體、斜體字、縮排、字體大小等)。因為XML文件的原始碼只是描述有哪些資料，讓讀者可以輕易地了解這份文件的內容以及結構。

XML文件也被稱為「自我描述」 (self-describing) 的文件，因為，每一份XML文件內都會包含一組資料必須遵循的規則。而由於每一組規則都可以重複使用，因此，文件建立者可以很容易地利用相同類別 (class) 文件的新版本。

Note

類別是出自物件導向的程式觀念，在物件導向的程式中，類別用於描述一群有相同特性的物件。基於各文件的內容種類，將文件建立類別，可以提供一種很有用的文件分類方法。

有效的與標準的XML文件

XML最有用的兩個特性是：提供文件結構化的能力，及提供資料自我描述的能力。要有這兩種能力，文件中必須要有遵循結構化 (structual) 與文法化 (grammatical) 的規則。接下來的兩小節，將簡單介紹兩個XML詞彙：「有效的」 (Valid) 和「標準的」 (Well-formed)，這兩者描述了文件如何遵循用來控制XML文件的結構化與文法化規則。

有效的(Valid)文件

XML文件處理器 (XML processor) 可強制執行XML文件執行文件內的結構和內容規則。這些規則包括標準XML規格所要求的部份，以及針對該文件所特別定義的規則。其中，第二種規則是以「文件型態定義」 (Document Type Definiton，簡稱DTD) 存在。DTD和XML文件中真正的資料部份是分開的，DTD可以直接包含在XML文件內部；也可以從XML獨立出來，成為一個獨立的文件。一個有效的XML文件必須嚴格地遵守這兩種規則。本書並不會詳細介紹如何撰寫及使用DTD文件，因為本書只針對簡單且不需DTD的XML例子來說明。您可以在任何專業的XML參考手冊或網站上找到更多撰寫DTD文件的資訊，例如XML in Action這本書 (by William J. Pardi，Microsoft Press 1999) 和3 www.w3.org/xml (W3C的XML網站)。正如您等一下看到的，XML文件不是非得要有DTD文件才行。

標準的 (Well-formed) 文件

標準的 (Well-formed) 文件所要遵循的規則遠不如有效文件嚴格。建立一個標準的XML文件其實是非常簡單且直覺的。以下列表會條列出標準化的XML文件主要規則。本章稍後也會舉一些例子。

  • 只有一個根元件 (Root Element，或稱為文件元件Document Element)
  • 根元件部份不能出現在文件中其它元件的內容中
  • 除了根元件之外，文件中其他元件的開始與結束標籤必須構成文件中的同一個巢狀層級。這意思是說，如果開始標籤放在一個元件的資料內容位置上，結束標籤也必須放置在同一個元件的資料內容位置。4

如果XML文件不遵循這些規則，瀏覽器將會出現錯誤訊息。在Internet Explorer瀏覽器中，可以利用Script語言透過物件模型 (Object Model) 來偵測錯誤。本章稍後也會有錯誤處理 (Error handling) 的詳細介紹。

我們來看看一個XML文件的例子：

<?xml version="1.0">
<PLANT>
   <COMMON>Columbine</COMMON>
   <BOTANICAL>Aquilegia canadensis</BOTANICAL>
</PLANT>

這個文件包含了一個PLANT文件元件 (稱為Document Element或根元件)，而COMMON和BOTANICAL是包含在根元件內部的元件。為了要講述這個觀念，以下一個例子是「非」Well-formed的文件，因為它包含了兩個根元件：

<?xml version="1.0">
<COMMON>Columbine</COMMON>
<BOTANICAL>Aquilegia canadensis</BOTANICAL>

元件的巢狀層級可建立父/子元件的關係。每個子元件 (非根元件的元件) 都會放置在其父元件之內，就像我們在第五章所討論的動態物件模型一樣。這個觀念我們用下面的例子來展示：

<ROOT>
   <PARENT1>
      <CHILD1></CHILD1>
      <CHILD2></CHILD2>
   </PARENT1>
</ROOT>5

子元件絕對不能放在其父元件的其它子元件之內。例如，下面這段原始碼就是一個非well-formed的XML文件：

<ROOT>
   <PARENT1>
      <CHILD1>
      <CHILD2></CHILD1></CHILD2>
   </PARENT1>
</ROOT>

同樣地，根元件的前後標籤也都不能放在其任一子元件的內部。下面的原始碼也不是一個Well-formed的XML文件：

<ROOT>
   <PARENT1>
      <CHILD1></CHILD1>
      <CHILD2></CHILD2>
   </ROOT>
 </PARENT1>

正如您所看到的，XML文件是非常結構化的文件，而且必須遵循嚴格但簡單的規則，以形成well-formed或valid的文件。這種結構加上特定的層級結構，產生了一個有父子元件關係的家族樹狀結構。

XML和Internet Explorer

截至目前為止，我們只介紹了XML的資料特性，而未介紹XML的顯示方式。接著您一定會有這個邏輯上的疑問，那就是該如何在網頁上顯示XML資料? Internet Explorer包含了幾個可以顯示XML資料的物件，最常被用到的就是DOMDocument物件。這個物件基本上扮演的是資料本身與Internet Explorer資料顯示功能的中介角色。6

當這個物件在分析一份文件時，它會在記憶體中建立文件內所有元件的樹狀結構；並提供使用XML文件物件模型 (XML Document Object Model) 的方法，也就是允許存取XML資料的介面。這個物件模型會顯露物件的性質、方法、事件、及包含在資料樹中真正的資料部份。詳細的XML文件物件模型的性質、方法、與事件，在本章稍後的表格21-1到21-3中可找到詳細的列表。物件模型可以讓設計者檢視從根到分支的所有樹狀結構。

程式列表21-1是一個簡單的網頁，它將XML資料送進網頁中，然後將它顯示在螢幕上。圖21-1顯示的是網頁的瀏覽結果。

<HTML>
<HEAD>
<TITLE>Code Listing 21-1</TITLE>
<SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="onload">
  start()
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
  var xmlDoc=new ActiveXObject("Microsoft.XMLDOM")
  xmlDoc.async=false
  xmlDoc.load("email.xml")

function start()
  var root=xmlDoc.documentElement
  todata.innerText=root.childNodes.item(0).text
  fromdata.innerText=root.childNodes.item(1).text
  ccdata.innerText=root.childNodes.item(2).text
  subjectdata.innerText=root.childNodes.item(3).text
  bodydata.innerText=root.childNodes.item(4).text

</SCRIPT>
</HEAD>
<BODY>
  <B>To:</B> <SPAN ID="todata"></SPAN><BR>
  <B>From:</B> <SPAN ID="fromdata"></SPAN><BR>
  <B>CC:</B> <SPAN ID="ccdata"></SPAN><BR>
  <B>Subject:</B> <SPAN ID="subjectdata"></SPAN><BR>
  <B>Body:</B> <SPAN ID="bodydata"></SPAN><BR>
</BODY>
</HTML>
程式21-1

圖21-1　一個簡單處理XML文件的HTML網頁

在<HEAD>中的第一段Script程式碼只是一個很簡單的事件處理器，其作用是在瀏覽器載入網頁後，執行start函式的呼叫。我們等一下會解釋這個函式。注意網頁本身包含了SPAN標籤，這些標籤所定義的區域將會是最後XML資料的顯示空間。7

我們先前有提到，XML處理器扮演的是XML文件與HTML網頁 (或任何其它類似的顯示媒體) 的中間媒介層。我們必須先將XML處理器載入，成為網頁上的一個物件，如此我們才能利用Script語言與之溝通。

var xmlDoc=new ActiveXObject("Microsoft.XMLDOM")
xmlDoc.async=false
xmlDoc.load("email.xml")

程式碼的第一行載入一個DOMDocument物件，然後將它設定給變數xmlDoc。如此提供使用XML處理器與物件模型的權利。下一行告訴處理器不要「非同步」(Asychronously) 載入文件，這個意思是說網頁會等到文件的資料完全下載後再繼續顯示網頁；設定值若改為TRUE，則會使資料與網頁的其他部分一起下載，如此一來，就得使用一些偵測 (通常會測試ondataavailable或onreadystatechange事件，或readystate性質)，來確定資料在被使用之前已載入。第三行則是讓物件載入本章一開始提到的email.xml這個XML文件。以下是資料樹狀結構一開始被載入的部份：

DOCUMENT
|---XMLDCL
|   |---ATTRIBUTE version "1.0"
+---ELEMENT EMAIL
    |---ELEMENT TO
    |   +---PCDATA "Bill_Pardi@hotmail.com"

此樹狀結構是以文件物件 (Document Object) 作為開端，它包含了一個XML宣告。接著是根元件EMAIL，EMAIL元件包含另一個元件，也就是上面結構圖中所顯示TO子元件，其值為Bill_Pardi@hotmail.com，這是一個叫做PCDATA的XML資料型態。

一旦網頁被下載，start函式就會被呼叫。這個函式其實十分簡單，其第一行會建立一個變數稱為root，並且設定給XML文件的根節點 (root node)，讓我們可以存取XML資料樹。下一行程式碼利用innerText性質，將一段文字設定給ID為todata的SPAN元件，如此可以讓文字被顯示，而它使用的文字是來自XML根元件的第一個子元件。利用root.childNodes.item(0).text這一段程式碼，即可存取根元件的第一個子元件，以取得文字內容。

Note

如果您能瞭解這段程式，您將會知道如何使用XMLDocument控制項來載入一份XML文件，且從XML的結構樹中取得資料。這是處理其他XML文件的基礎。8

雖然上面講的文件所要花費的功夫，要比簡單且可得到相同效果的HTML文件來得多。但是，其實一些使用XML會有的優點我們可以從中瞭解，最大的優點是網頁可以變成一個範本資料。上面所建立的HTML網頁可以當作其它可以事先定義模組的XML資料的範本。雖然建立一個HTML文件會需要花一點功夫，但它可重複使用於不同的內容。舉例來說，XML文件即使被翻譯成法語、德語…等其它語言，仍然可以被插入同一個HTML文件中。

除了利用DOMDocument物件外，我們還可以用其它的方法可以將XML資料顯示成網頁，例如: XML資料來源物件 (Data Source Object)、XSL、和XSL Pattern。這些技術加入了更多使用XML將資料結構化和儲存資料的好處，您可以在微軟SBN Workshop網站和隨書附贈光碟中找到更多相關資訊。在隨書CD中，要看XML的資料，請在XML TOC (XML Table of Contents) 中選擇任何一個主題即可。若要參考線上版本，可連上MSDN線上資源網站 msdn.microsoft.com/resources/schurandhtml.htm ；或者也可以直接開啟隨書光碟中檔名為MSDN_OL.htm的檔案，然後選擇XML項目。下面的表格分別列出XML文件物件模型中的各項性質。

表21-1　XML文件的性質
性質 | 說明9
async | 回傳一個布林值，決定是否允許非同步下載。當允許非同步下載時，傳回值為TRUE；若不允許則傳回值為FALSE 。讀/寫。
attributes | 傳回包含目前節點元件之屬性集合物件。若節點不能有屬性值，則傳回值為null。唯讀。
childNodes | 傳回包含目前節點元件之所有子節點元件的集合。若目前節點沒有任何子節點，則傳回值為null。唯讀。
doctype10 | 傳回一個包含擁有DTD的文件型態節點。若不含DTD，則傳回值為null。唯讀。
documentElement | 傳回一個包含根元件資料的物件。若沒有根元件，則傳回值為null。唯讀。
firstChild | 傳回一個包含目前節點的第一個子節點元件，若目前節點沒有任何第一子節點，則傳回值為null。唯讀。
implementation | 傳回DOM為目前XML文件實作所得的物件。唯讀。11
lastChild | 傳回一個包含目前節點的最後一個子節點元件，若目前節點沒有任何最後一個子節點，則傳回值為null。唯讀。
nextSibling | 傳回一個包含目前文件節點在子節點元件集合中的下一個兄弟元件，若目前節點沒有任何兄弟節點，則傳回值為null。唯讀。
nodeName | 傳回一個能代表合格的目前節點(元件，屬性，或實體參考)名稱字串，唯讀。
nodetype12 | 傳回一個數字，它分別代表目前節點的DOM型態 (元件、屬性、文字)。唯讀。
nodeValue | 傳回特定節點的相關純文字資料，這不是元件的資料值，而是未剖析相關於節點的純文字，就好像是屬性和處理指令(PI)，某種資料型態會回傳null。讀/寫。
ondataavaiable | 設定Ondataavaiable事件處理，只能寫。
onreadystatechange | 設定Onreadystatechange事件處理，只能寫。13
ownerDocument | 傳回一個物件，它包含目前節點的文件之根節點。唯讀。
parentNode | 傳回包含目前節點元件之所有父節點元件的集合。若目前節點沒有任何父節點，則傳回值為null。唯讀。
parseError | 傳回一個DOM剖析錯誤物件，它描述了最後的剖析錯誤。若沒有錯誤發生，則傳回0。唯讀。
previousSibling14 | 傳回一個包含目前文件節點在子節點元件集合中的上一個兄弟元件，若目前節點沒有任何兄弟節點，則傳回值為null。唯讀。
readyState | 傳回一個數字表示目前的XML文件的狀態。唯讀。值如下所示： 0 (尚未初值化) XML物件已經建立，但尚無任何文件載入 1 (載入中) 正在載入，但剖析尚未開始。 2 (載入後) 文件的部分已經下載且開始剖析，但還建立為物件模型。 3 (互動的) 文件已載入的部分之物件模型已經建立。15 4 (完成的) 文件完全被載入。這並不表示載入成功。
url | 傳回最後一個成功下載文件的URL。若文件只存在記憶體中(非從外部檔案載入)，則傳回null值。唯讀。
validateOnParse | 提示給剖析器文件是否被確認。若為True，則當被剖析時文件是被確認的，若為false，文件並無被確認，且被期望為well-formed。讀/寫。
xml | 傳回特定節點和其子孫的XML呈現。唯讀。16
表21-2　XML文件的方法
方法 | 說明
abort() | 若這個方法在非同步下載期間被呼叫，所有的解析動作將被停止，在記憶體中文件的任何部分也將被拋棄。
appendChild(newChild) | 新增一個節點當作特定節點的最後一個節點。17
cloneNode(deep) | 建立與一個特定節點完全相同的複製節點，deep參數是一個布林值，若為True，則不只複製節點而且還複製其子孫元件。若為False，只有特定節點與其屬性被複製。
createAttribute(name) | 建立一個特定名稱的屬性。
createCDATASection(data) | 建立一個CDATA區段，其中包含特定字串資料。
createComments(data)18 | 建立一個特定字串的註解。
createCommentFragment() | 建立一個新的文件片段，不過並不把它加入文件樹中。若要將它加入樹中，必須利用insert方法，例如insertBefore、replaceChild、或appendChild。
createElement(tagName) | 建立一個特定標籤名稱(大小寫不同)的元件。
createEntinyReference | 建立一個特定名稱的實體參考，不過並不把它加入文件樹(name) 中。若要將它加入樹中，必須利用insert方法，例如insertBefore、replaceChild、或appendChild。19
createNode(type,name, | 設定特定型態、名稱及名稱空間建立一個新的節點。namespaceURL)
createProcessingInstruction | 建立一個包含特定目標和資料的處理指令，不過並不把它(target,data) 加入文件樹中。 若要將它加入樹中，必須利用insert方法，例如insertBefore、replaceChild、或appendChild。
createTextnode(data) | 建立一個包含特定資料的新文字節點，不過並不把它加入文件樹中。若要將它加入樹中，必須利用insert方法，例如insertBefore、replaceChild、或appendChild。
getElementsByTagName20 | 傳回一個特定名稱的元件集合。使用 "*" 的標籤名稱設定，tagname)則會傳回所有在文件能找到的元件。
haschildnodes() | 傳回True若節點含有子元件，false則沒有。
InsertBefore | 在參考節點之前插入一個新子節點,newChild參數是一個包(newChild,refChild)含新子節點位置的物件，而refChild是參考節點的位置。若不包含refChild參數，新的子節點會被插入在子節點集合的最後位置。
load(url) | 從特定的位置中載入指定的文件，傳回True若文件載入成功，傳回False則為否。21
loadXML(xml/string) | 載入一個XML文件，或從字串來的文件片段，傳回True若文件載入成功，傳回False則為否。
nodeformID(idString) | 傳回一個符合特定值的節點，若有符合的物件則傳回此物件，若此操作失敗，傳回null值。
Parsed | 若目前節點和此節點的所有的子孫節點，已經被剖析及，則傳回值為True，若節點的任何部分都尚未被剖析，則傳回null。
removeChild(child)22 | 從節點集合中刪除特定的子節點，child參數就是包含要被刪除的子節點之元件。
replaceChild | 用提供的新節點來取代舊節點。若newChild是null，則舊(newChild，oldChild) 節點不會被取代，而直接刪除。
selectNodes(patternString) | 傳回一個節點集合元件，此元件包含符合提供XSL pattern的節點。
selectSingleMode | 傳回第一節點符合所提供的XSL pattern，若沒有發現任何(Pattern String) 符合，則傳回null。23
TransformNode(stylesheet) | 傳回一個字串包含目前節點的處理結果和它的子節點使用所提供的XSL樣式。
表21-3　XML文件的事件
事件 | 說明
Ondataavailable | 當任何資料可用則會引發此Ondataavailable事件。這個技巧並不提示在這個文件中有多少資料是可用。24
Onreadystatechange | 當readystate性質改變，則會引發Onreadystatechange事件，但此事件並不會提供ready state的設計值，必須使用readystate性質來取得目前狀態。

基礎之外的其它Scripting技術

上面介紹的簡單E-Mail範例，示範了如何存取XML物件模型，以及使用XML資料。若進一步來觀察這個文件和它的script，我們將會看到簡單所帶來的代價。在我們想盡辦法讓Script簡單一些時，我們加入了一些技巧在其中，以證明script在許多情況下還是不夠理想的。請考慮下面的問題：

  • 用來存取XML文件樹和讀出資料的script程式，會假定我們不僅知道有多少元件存在，同時也知道元件的順序和我們的原始檔是相同的，因為我們是利用索引來使用每個元素。這類的script程式也許可以用在一些應用程式上，但在其他應用程式上可能就不太適合了。
  • script程式能分別為每個元件設定位置。這種做法用在小型文件上可能沒什麼問題；可是如果用在大型或複雜的文件上，則整個處理程序會變得過於冗長，而且很可能錯誤百出。
  • HTML文件並不完全是資料獨立的文件，因為用來配置版面和設定格式的HTML標籤會跟文字 (如前一個例中的To：和From：) 夾雜在一起。若文件必須要翻譯成其他語言，則會需要同時編輯XML文件與HTML兩種文件。25

我們現在就來看一些script的寫作技巧，以避免我們剛剛所講的問題。

處理XML文件樹

在上一個例子中，設計者必須知道XML文件中元件的數目和類型，但是如果能使用一些XML物件模型中的其它性質和方法，那麼事情就會簡單一些。

在這些有用的性質當中，其中有一個是childNodes，這個性質會傳回目前節點的子節點集合。ChildNodes的length性質會包含子節點的數目。因此，處理節點的子節點將會非常容易。參考如下程式碼21-2。

<HTML>
<HEAD>
<TITLE>Code Listing 21-2</TITLE>
<SCRIPT LANGUAGE="JavaScript">
  var xmlDoc=new ActiveXObject("Microsoft.XMLDOM")
  xmlDoc.async=false
  xmlDoc.load("email.xml")
  root = xmlDoc.documentElement

  for (var i=0; i<root.childNodes.length; i++){
    alert(root.childNodes.item(i).nodeName+" = "+
          root.childNodes.item(i).text)
  }
</SCRIPT>
</HEAD>
</HTML>
程式21-2

26
圖21-2　對話窗包含第一個元素的名稱與內容

現在載入HTML文件後，應該會一連串產生5個對話窗，每個對話窗都會包含元件在XML文件中的名稱與內容。第一個對話窗如圖21-2所示。處理的程式利用了root.childNodes.length性質來詢問XML文件，以得知根元件包含了多少個子元件。接著，script會進入一個迴圈，巡行檢視根元件的所有子元件，並取得每一個子節點的名稱 (利用nodeName性質) 和文字內容，直到最後一個節點為止。

不過，這個程式處理結構樹的第一層而已，若根元件的任何子元件也有子元件，則會被程式21-2所忽略。Inbox.xml檔案是較為複雜的文件 (下面所列的文件，放在書附光碟chap21\inbox.xml目錄中) ，此文件是一個多層的樹結構。注意第一個email甚至包含一個元件(CC)，這是在其它email所沒有的。

<?xml version="1.0"?>
<INBOX>
  <EMAIL>
    <TO>Bill_Pardi@hotmail.com</TO>
    <FROM>Eric_Schurman@hotmail.com</FROM>
    <CC>DHTML_in_Action@hotmail.com</CC>
    <SUBJECT>My document is a tree.</SUBJECT>
    <BODY>This is an example of a tree structure.</BODY>
  </EMAIL>
  <EMAIL>
    <TO>Bill_Pardi@hotmail.com</TO>
    <FROM>Eric_Schurman@hotmail.com</FROM>
    <SUBJECT>XML is cool.</SUBJECT>
    <BODY>This is a simple message.</BODY>
  </EMAIL>
  <EMAIL>
    <TO>Bill_Pardi@hotmail.com</TO>
    <FROM>Eric_Schurman@hotmail.com</FROM>
    <SUBJECT>Here is that code.</SUBJECT>
    <BODY>I send too many emails.</BODY>
  </EMAIL>
</INBOX>

這需要更複雜的script才能得到和程式21-1相同型態的結果，也就是顯示在瀏覽器中的email內容。程式21-3從XML文件起頭開始，然後漸漸地由上往下巡行，並且顯示每一個節點的內容。如果有一個節點有子節點，其子節點將會被檢視，並且顯示其內容。圖21-3顯示執行此程式的結果。

<HTML>
<HEAD>
<TITLE>Code Listing 21-3</TITLE>
<SCRIPT LANGUAGE="JavaScript">
  var xmlDoc = new ActiveXObject("microsoft.xmldom")
  xmlDoc.async=false
  xmlDoc.load("inbox.xml")
  root=xmlDoc.documentElement
  newHTML=""

function start(){
  buildTree(root)
  content.innerHTML=newHTML
}

function buildTree(passedNode){
  var children = passedNode.childNodes.length
  for (var j=0; j<children; j++){
    Node=passedNode.childNodes.item(j)
    if (Node.nodeName=="EMAIL"){ newHTML+=("<P>"+Node.nodeName+" "+j) }
    if (!Node.hasChildNodes()){
      newHTML+=( "<BR><B>"+Node.parentNode.nodeName+":</B> "+Node.text )
    }
    buildTree(Node)
  }
}
</SCRIPT>
</HEAD>
<BODY onload="start()">
<SPAN ID="content"></SPAN>
</BODY>
</HTML>
程式21-327

圖21-3　顯示XML文件的內容

我們一起從頭到尾來看一下這個程式。當文件被載入後，script區塊會載入XML檔案，將XML的根元件設定給變數root，接著建立空白newHTML變數，這個變數等一下在script中會用到。當文件結束載入，在BODY標籤中的onload事件處理會呼叫start函式，此函式會輪流呼叫buildtree函式，並傳送XML根元件給它。

這個例子主要運作是由buildTree函式來完成的，這是一個遞回函式，也就是說當一些特殊情況發生時，它會自己呼叫自己。這個函式基本上可以檢視目前節點，及檢查每個節點多少個子節點。若節點含有子節點，這函式會再次呼叫自己一次，傳入第一個子節點給自己。一旦下達一個沒有子節點的節點，它會加入newHTML變數及一些HTML原始碼，來描述目前節點的資料，然後往上一層回到它的父節點。藉由重複這樣的動作，它可以巡行檢視整個資料樹。接著，來深入看一個函式的片段:

var children = passedNode.childNodes.length
for (var j=0; j<children; j++){

函式一開頭就找出目前有多少子節點，然後將值設定給children變數。下一行由一個for迴圈開始，它會針對目前節點的每一個子節點重複執行。

Node=passedNode.childNodes.item(j)
  if (Node.nodeName=="EMAIL"){ newHTML+=("<P>"+Node.nodeName+" "+j) }
    if (!Node.hasChildNodes()){
      newHTML+=( "<BR><B>"+Node.parentNode.nodeName+":</B>28

接著，目前的子節點會被設定給Node變數。由於我們希望資料中的每一個email都可以分開，因此加入了上面的第二行。若節點的名稱為 "EMAIL"，則除了這個節點的名稱和號碼之外，還會加入段落標籤 <P>到newHTML中，我們也測試是否Node.parentNode==root，因為只有在root之下的元件才有可能是EMAIL元件。

BuildTree(Node)

For迴圈的最後一行再次呼叫buildtree函數，並傳目前節點過去。最後，每個元件都呼叫了此函式。更彈性且有完整功能的XML tree巡行程式可以在 Microsoft.com/gallery/sample/xml/tree_viewer/default.asp 或在隨書光碟中找到，請參閱Tools and Samples和XML Tree viewer部分。

您應該可以注意到，使用這些技巧可以讓HTML文件更加彈性且功能更強，雖然這個文件只是一個特定類型的XML文件範本而已。但是這樣的技巧卻讓HTML與XML能完美的互相補強。

錯誤處理29

XML的物件模型提供了許多方法給設計者來處理XML文件所產生的錯誤。其中一個是文件物件的parseError性質，它提供了XML文件發生問題時的資訊，讓設計者可以進行處理。基本上，使用者可能不會需要去處理這樣子的錯誤。

ParseError性質提供了每個可能發生錯誤的程式碼。設計者可以使用這些程式做下列事情：

  • 幫忙為XML文件與script除錯。
  • 告知使用者問題所在，並提供建議的解決方案。
  • 將某種錯誤攔截，然後在背景修復錯誤。

下面的程式碼說明parseError如何告知使用者發生問題。

Var xmlDoc = new ActiveXObject("Microsoft.xmldom");
XmlDoc.load("email.xml");

If (xmlDoc.parseError.reason == " ") {
  Alert("Document loaded successfully")
}
else {
  alert("The Following error occurred:"+xmlDoc.parseError.errorCode)
}30

這個技巧可以用於除錯和讓使用者可以避開錯誤。

XML Data Island

在剛剛的例子，我們將XML當作一個資料來源，並將HTML當作顯示的方法。當HTML文件被顯示時，XML與HTML會被當作是兩個互相影響的獨立文件。另一個選擇是使用XML data islands。Data islands可以讓設計者在HTML文件直接包括XML片段。不過對於這個方法的效果，目前有正反兩種意見，正面的意見是：

  • 您不需分離出XML文件
  • 您不需利用script載入XML資料
  • 您不需透過使用Object元素或ActiveXObject物件

另外也有一些負面的意見，端視如何使用data islands：31

  • XML data不再獨立於HTML檔案
  • 對於其他應用程式或HTML文件，XML data失去了可攜性
  • 如果XML的原始碼散落在HTML原始碼中，XML也許會更難管理。XML Data Islands可以是行內XML或外部連結XML文件。

處理行內XML Data Islands

要使用行內XML Data Islands，只要很簡單地直接插入一段XML程式碼到HTML文件就好。XML文件的內容放在<XML></XML>這一組標籤中。為了示範，我們修改程式列表21-1 ，將email.xml嵌入到html文件中，然後將程式碼改變成程式列表21-4。產生的結果和先前的例子完全一樣，如圖21-1。

<HTML>
<HEAD>
<TITLE>Code Listing 21-4</TITLE>

<XML ID="email">
  <EMAIL>
    <TO>Bill_Pardi@hotmail.com</TO>
    <FROM>Eric_Schurman@hotmail.com</FROM>
    <CC>DHTML_in_Action@hotmail.com</CC>
    <SUBJECT>Basic email</SUBJECT>
    <BODY>This is an XML-based email.</BODY>
  </EMAIL>
</XML>
<SCRIPT LANGUAGE="JavaScript">
function start(){
  xmlDoc=email
  var root=xmlDoc.documentElement
  todata.innerText=root.childNodes.item(0).text
  fromdata.innerText=root.childNodes.item(1).text
  ccdata.innerText=root.childNodes.item(2).text
  subjectdata.innerText=root.childNodes.item(3).text
  bodydata.innerText=root.childNodes.item(4).text
}
</SCRIPT>
</HEAD>
<BODY onload="start()">
  <B>To:</B> <SPAN ID="todata"></SPAN><BR>
  <B>From:</B> <SPAN ID="fromdata"></SPAN><BR>
  <B>CC:</B> <SPAN ID="ccdata"></SPAN><BR>
  <B>Subject:</B> <SPAN ID="subjectdata"></SPAN><BR>
  <B>Body:</B> <SPAN ID="bodydata"></SPAN><BR>
</BODY>
</HTML>
程式21-432

首先注意當行內XML Data包含在<XML>標籤中，<XML>元素並不是根節點。反之，它是一個HTML標籤，讓瀏覽器可以辨別包含在<XML>標籤之內就會被當作是XML。也要注意一下<XML>標籤有ID屬性，所以它可以被script叫用。新的程式碼xmlDoc=email相等於使用XMLDOM ActiveXObject，然後會載入一個特定的XML文件。事實上，使用的還是同一個處理程式；只是用不同的方法來存取而已。除了行內XML Data Island，還有一個方法可以用連結外部的XML文件來使用<XML>標籤。

處理連結XML Data Islands

要利用<XML>標籤來連結XML文件，您只要使用<XML>標籤的SRC屬性就好。我們可以利用下面的程式碼，來取代上述的文件中之整個文件元素。

<XML ID="email" SRC="email.xml"></XML>

此執行結果和前面例子完全相同。這個好處在於XML資料仍然與html文件分離。本質上，這個方法處理的方式十分像ActiveX Control方式，除了瀏覽器必須負責處理control及載入文件以外。

<XML>標籤的屬性

<XML>標籤包含，某些額外的屬性，當文件載入後，發生的事件可提供更多的控制。33

VALIDATEONPARSE屬性指出當它被解析時，文件是否應該被確認。它的預設值為True。下面是一個例子：

<XML ID="xmlDoc" SRC="xmldoc.xml" VALIDATEPARSE="false"></XML>

ASYNC屬性意指是否文件要非同步下載。它的預設值為True。下面是一個例子：

<XML ID="xmlDoc" SRC="xmldoc.xml" ASYNC="false"></XML>

XML是否為所有發生在web上問題的解決方案？或者只是個誇大的宣傳？事實上都不是。XML已經獲得不同領域的業界所支援，而不僅僅是在Web上而已。這表示會有許多承諾，特別是在不同的瀏覽器都能支援XML的情況下。本章只是提供十分簡單的XML概略說明，您可以在W3C網站www.w3.org，及一本不錯的XML參考手冊( XML in action by William J. Pardi Microsoft Press) 中找到更多XML的資訊。


實戰Dynamic HTML網站技術=>額外新技術

額外新技術
小
工
具 加入書架
加入書籤
上一章
下一章

本章涵蓋的是一些我們認為蠻重要的進階主題，包括：對一般ActiveX控制項(Active Control) 的支援、scriptlet技術、HTML Behaviors、cookies、HTML Applications、頻道(Channels)、和分級系統(Ratings System)。受限於篇幅的長度，雖然無法逐一深入討論每一個主題，但我們會儘可能地提供概觀性的介紹。

使用ActiveX控制項

由於3.0版以後的Microsoft Internet Explorer以及一些主要的開發環境 (例如Microsoft Visual InterDev和Microsoft Visual Basic) 提供了對ActiveX的支援，因此對於開發者來說，要在Windows程式中加入ActiveX控制項並不會太困難。雖然Netscape目前並沒有直接支援ActiveX，但是我們還是可以透過由NCompass Labs Inc.所開發的一個Plug-in (您可以在 www.ncompass.com1 找到)，讓Netscape Navigator提供對ActiveX的部份支援。

ActiveX控制項本質上是一些遵循了某些特定標準的傳統程式 (就跟那些用C++ 或Visual Basic寫出來的程式一樣)。這些程式可以在其它程式 (其中大部分都是瀏覽器) 中使用，以擴充程式本來所沒有的功能。在本書所參考的內建控制項中，其中很多就是ActiveX控制項，例如：表格資料控制項和結構化圖形控制。除了內建的控制項以外，您也可以從微軟網站或其他公司的網站上找到數以千計的控制項。

不論控制項來自哪裡，將控制項加入到網頁的方法基本上都相同，您可以利用Object元件來加入其他非內建的控制項。

Note

為了讓那些使用NCompass ScriptActive Plug-in的Netscape Navigator使用者能在網頁上能使用ActiveX控制項，開發者不能只是用Object元件而已。因為這個plug-in (跟所有的plug-ins一樣)，必須使用<EMBED> 標籤來啟動使用。 NCompass提供了一個工具，可用來轉換那些已經使用了標準 <OBJECT> 標籤的網頁，以方便在網頁中也能加入 <EMBED> 標籤。需要更多有關使用ScriptActive網站的資訊，請到NCompass Labs網站 ( http://www.ncompass.com/ )詢問。

剖析OBJECT2

當在網頁中使用協力廠商(Third-party)所設計的ActiveX控制項，您會需要使用 <OBJECT> 標籤來包住控制項，就跟使用內建控制項一樣。當客戶端系統中沒有所需的控制項時，那麼您將會需要提供額外的資訊，如程式列表22-1所示。這個程式設定了一個很受歡迎的ActiveX控制項 — Macromedia Flash控制項。由於這個軟體也有Netscape的Plug-in版本， 所以程式中也加入了 <EMBED> 標籤。

注意在程式列表22-1中的CODEBASE屬性，根據這個屬性的設定，Internet Explorer允許軟體下載或安裝。在這個例子中，CODEBASE屬性指定了一個CAB檔案的位置(URL)。基本上，CAB檔案是一個壓縮檔案，它包含了將ActiveX控制項安裝到使用者電腦中時，所需要的所有檔案。若網頁在一個沒有安裝這個ActiveX控制項的電腦中被開啟，則CAB檔案(由使用者自由選擇)將會被下載、解開並安裝。如此，網頁稍後才可以正常載入並執行。

<HTML>
<HEAD>
<TITLE>Listing 22-1</TITLE>
</HEAD>
<BODY>
<OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
 CODEBASE="http://active.macromedia.com/flash2/cabs/	   swflash.cab#version=3，0，0，0"
 ID=INDEX WIDTH=95% HEIGHT=95%>
 <PARAM NAME="movie" VALUE="myFile.swf">
 <PARAM NAME="loop" VALUE="false">
 <PARAM NAME="quality" VALUE="high">
<EMBED SRC="myFile.swf" LOOP="false" QUALITY="high" SWLIVECONNECT="false"
  WIDTH="95%" HEIGHT="95%" TYPE="application/x-shockwave-flash"
  PLUGINSPAGE="http://www.macromedia.com/shockwave/download/
    index.cgi?P1_Prod_Version=ShockwaveFlash">
</EMBED>
</OBJECT>
</BODY>
</HTML>
程式22-1

在CODEBASE屬性設定的最後，您可以看到控制項的版本資訊。系統將會使用這個資訊，來比較系統中已有的控制項與即將下載的控制項的版本，以確定系統能使用最新的版本。為了讓這個過程順利執行，CAB檔案必須適當地被建立，且指定的位置必須正確。

除了包含在CODEBASE設定中的額外資訊以外，基本上，不管是內建與外部控制項，其OBJECT元件的用法都是一樣的。大部分的控制項有自己特有的屬性、性質、和方法，並可透過腳本語言來設定，不過前提是控制項的設計者必須提供使用控制項的詳細資訊。

Scriptlet3

Scriptlet本質上是一個小型的網頁，但是它可以當作其它網頁或應用程式的元件來用。Scriptlet遵循了一組標準，讓那些包含了Scriptlet的網頁或應用程式，在存取由控制項設計者提供的scriptlet屬性、方法、和其它內容時有規則可循。Scriptlet可以被任何支援ActiveX控制項的應用程式所使用 (本章稍後介紹的DHTML Behavior其實和scriptlet很類似，不過DHTML Behavior則提供了更多的彈性以及向下的相容性)。使用scriptlet有一個好處，就是您建立的其實是一個可重複使用的程式模組，這個程式模組可以加入到其他網頁來使用。舉例來說，假設您正在開發一個網站，且網站上的所有網頁都包含了使用者介面(UI)元件(例如一個工具列或按鈕列)，雖然這些介面都很像，但根據元件使用地方的不同，其運作方式也不同。在這種狀況下，您就可以將UI元件製作成Scriptlet，然後針對每個網頁的需求，存取適當的Scriptlet性質或方法。

Note

所有的平台 (包括Microsoft Windows、Macintosh、和UNIX) 上的Internet Explorer 4.0或更新的版本都支援scriptlets。Netscape Navigator則尚未出現支援scriptlet的版本。如果您試著用Netscape來檢視一個包含scriptlet的網頁，則網頁只會地顯示沒有scriptlet部份的簡單網頁而已。

想要將scriptlet加入網頁中，得先建立一個具有適當大小的 <OBJECT> 標籤，並且在標籤內加上text/x-scriptlet的TYPE屬性，以及包含連結目標scriptlet之URL的DATA屬性。請參考下列程式碼：

<OBJECT TYPE="text/x-scriptlet"
  WIDTH="50" HEIGHT="80" DATA="myfile.htm">
</OBJECT>

其實要建立scriptlet也很簡單，因為說穿了，Scriptlet本身其實就是一個動態網頁(Dynamic HTML page)。因此您只要對動態網頁和script腳本語言有基本的瞭解就可以了 (既然本書您已經看到的這裡了，相信您應該已經對這兩者已經有相當的認識了)。在程式列表22-2中，我們已經建立好一個網頁，並準備拿它來當作另一個網頁的scriptlet，這個Scriptlet網頁在瀏覽器中的顯示結果只是簡單的一行文字。請注意雖然下面的這個網頁中已經包括了script ，但因為還沒有可呼叫script的機制，所以script程式目前依然是無法執行的。

<HTML>
<HEAD>
<TITLE>Listing 22-2</TITLE>
<SCRIPT LANGUAGE="JavaScript">

function public_chngText(sNum， sText){
  label.innerHTML=""
  for (var i=1; i<=sNum; i++){
    label.innerHTML+="<SPAN STYLE='font-size:"+i*5+"'>"+sText+" </SPAN>"
  }
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#CCCCCC">
<B><SPAN ID="label">Text</SPAN></B>
</BODY>
</HTML>
程式22-24

要在網頁中使用scriptlet的函式和性質，您必須使用public來建立識別。有兩個方式可以完成這個動作：第一個方法是建立一個public_description物件；另一個則是在元件的名稱前加上public_ 。在程式列表22-2中，我們使用的是第二個方法，也就是public_chngText。如此一來，任何包含這個scriptlet的網頁就可以透過點表示法 (例如myScriptlet.chngText) 來參考Scriptlet的函式或屬性，就好像這些函式或屬性是scriptlet的一個子元件一樣。不過如果是在Scriptlet自身的網頁中存取這些函式或屬性，則可以省略public_ 的這些前置文字。

另一個方法是建立一個public_description物件，用這種方法建立的識別，則除了可以存取chngText函式外，也將可以存取Scriptlet的背景顏色。這其實十分類似Jscript的建構元函式 (constructor functions；曾在第8章討論過)。這個方法十分方便，因為所有scriptlet的公開部分都可以在同一個位置找到。在程式22-2中，我們建立了一個public_description物件，如下所示：

var pub_description=new InitScriptlet()
function InitScriptlet(){
  this.bgcolor=document.bgcolor
  this.chngText=chngText
}

若我們已經使用這個public_description物件， 則除了chngText函式以外，我們將還可以存取scriptlet的背景顏色。在使用public_description物件時，函式和性質不需要加上前置文字public_。

程式列表22-2中，包括了一個JScript函式，可在螢幕上以指定的次數重複顯示一段文字；並且在每次重複時，逐漸增加顯示文字的大小。如果只是顯示這個網頁本身時，使用者將只能看到設定在SPAN標籤內的預設文字，也就是Text。這是因為腳本語言尚未被執行，因此預設的文字還不會被改變。

程式22-3使用了OBJECT元件，並且分別在三個不同的位置上叫用scriptlet。請看圖22-1的顯示結果。

<HTML>
<HEAD>
<TITLE>Listing 22-3</TITLE>
</HEAD>
<BODY>
<OBJECT ID="TextRepeater" WIDTH="500" HEIGHT="100"
  TYPE="text/x-scriptlet"  DATA="lst22-2.htm">
</OBJECT><P>
<FORM NAME="F1">
Number of repeats: <INPUT TYPE="Text" NAME="repeats" VALUE="1" SIZE="1">
Display text: <INPUT TYPE="text" NAME="newtext" VALUE="Text">
<INPUT TYPE="button" VALUE="Change"
  ONCLICK="TextRepeater.chngText(F1.repeats.value， F1.newtext.value)">
</FORM>
<OBJECT ID="TextRepeater2" WIDTH="200" HEIGHT="100" ALIGN="left"
  TYPE="text/x-scriptlet"  DATA="lst22-2.htm"></OBJECT>
<OBJECT ID="TextRepeater3" WIDTH="275" HEIGHT="100"
  TYPE="text/x-scriptlet"  DATA="lst22-2.htm"></OBJECT>
<SCRIPT FOR="window" EVENT="onload" LANGUAGE="JavaScript">
  TextRepeater2.chngText(4， 'Sample')
  TextRepeater3.chngText(6， 'Code')
</SCRIPT>
</BODY>
</HTML>5
程式22-3

圖22-1　第二個網頁所建立的按鈕允許在scriptlet外面呼叫public函式

在程式列表22-3中，scriptlet的第一個會載入它的預設狀態。此時，網頁上會出現兩個文字欄以及一個按鈕，讓使用者可以改變第一個scriptlet的內容。一旦網頁被載入後，透過程式最後的一段script程式 (這段程式碼若放在標頭，也會有相同的結果)，scriptlet其次的兩個行程會跟著改變。這一段script會呼叫每個scriptlet的chngText函式，以設定顯示文字的內容和重複的次數。

透過呼叫window.external.bubbleEvent() 方法，scriptlet可以將發生的事件傳遞給使用了這個主網頁。不過這個方法只能傳目前所發生的事件給host網頁。scriptlet除了可以透過window.external.raiseEvent方法傳遞一般的事件外，也可以讓您建立快顯功能表(按下右鈕後顯示)。您可以在SBN Workshop網站上，學習到更多有關一般事件、快顯功能表、和scriptlets的相關訊息。或者也可以在書附光碟中，參考Workshop(Refernces);Component Development; DHTML Scriptlets。若網路已經建立連線，則請連上MSDN Online Resource網站上的 msdn.microsoft.com/resources/schumandhtml.htm 目錄。或者也可以在書附光碟中開啟檔案MSDN_OL.htm，然後選擇DHTML Scriptlets。6

Behavior

通常script和實際要顯示的內容通常都是一起存在網頁中的，因此有些script的功能可能會不小心被內容編輯者或是網頁編輯者破壞。為了避免這種情形，DHTML Behaviors提供了一種方法，以將script的功能和它所影響的網頁內容分離。

DHTML Behavior可以用HTML Components (HTC) 或其它傳統的程式語言 (例如C++) 來設計。在這裡，我們將把焦點放在HTC的使用上，因為C++ 並不包括在本書討論範圍內 (您可以從SBN Workshop找到更多有關使用C++ 來設計behavior的資訊。請參考書附光碟：Workshop (References)；DHTML， HTML， CSS；DHTML Behaviors；C++ References)。其實HTC本身也是標準的HTML檔案，只是HTC中包含了script和一些特定的HTC標籤。在其它網頁中的元件可以使用behavior CSS屬性來取得HTC的功能。 HTC可以將其性質、方法、和事件 (包括一般事件) 曝露給包含HTC的網頁，並可以輪流取得所在網頁的物件模型。 程式列表22-4示範了一個可以展開和折疊的清單，同時也展示了一些透過DHTML Behavior執行的方法與性質。圖22-2和22-3展示其結果。

<HTML>
<HEAD>
<TITLE>Listing 22-4</TITLE>
<STYLE>
  DIV {cursor:hand;margin-left:2em}
  .ExpandingHead{behavior:url(ExpMenu.htc)}
</STYLE>
</HEAD>
<BODY>
<DIV ID="Item1" CLASS="ExpandingHead"><B>Level 1 Item 1</B>
  <DIV>Level 2 Item 1</DIV>
  <DIV>Level 2 Item 2</DIV>
    <DIV CLASS="ExpandingHead"><B>Level 2 Item 3</B><BR>
      <DIV>Level 3 Item 1</DIV>
      <DIV>Level 3 Item 2</DIV>
    </DIV>
  <DIV>Level 2 Item 4</DIV>
</DIV>
<DIV CLASS="ExpandingHead"><B>Level 1 Item 2</B>
  <DIV>Level 2 Item 1</DIV>
  <DIV>Level 2 Item 2</DIV>
</DIV>
<FORM>
<INPUT TYPE="BUTTON" VALUE="Run Item1.showChildren()"
       onclick="Item1.showChildren()">
<INPUT TYPE="BUTTON" VALUE="Display item1.iChildren"
       onclick="alert(Item1.iChildren)">
</FORM>
</BODY>
</HTML>
程式22-4

其實網頁主體的程式碼很簡單。首先，在清單中的每個項目都是一個DIV元件，如果某個清單項目的DIV元件內還包含其它的項目，那麼就為這個DIV元件設定ExpandingHead類別。ExpandingHead類別定義在網頁一開頭的整頁樣式表中，它包含了behavior這個CSS屬性，並且指向檔案ExpMenu.htc 。

7
圖22-2　在沒有標題被按下之前的清單

圖22-3　程式22-4顯示清單在Netscape Navigator中完全展開的情況

ExpMenu.htc檔案的內容如下所列，且儲存在書附光碟中的chap22/ExpMenu .htc，這個檔會包含了該behavior本身。

<PUBLIC:HTC URN="www.microsoft.com">
<SCRIPT language="JavaScript">
  attachEvent("onclick"， toggleDisplay)
  function toggleDisplay(){
    // Hide/unhide all child objects (start at 1 so heading is skipped)
    for (var i=1; i<children.length; i++){
      children[i].style.display=(children[i].style.display==""?"none":"")
    }
    // Prevent click on sub item from collapsing whole menu
    if(window.event){window.event.cancelBubble=true}
  }
  // Collapse menu when first loaded
  toggleDisplay()

  function showChildren(){
    // Return list of child items
    var Txt=""
    for(var i=1;i<children.length;i++){Txt+=(children[i].innerText+"\n")}	    alert(Txt)
  }

  iChildren=children.length
</SCRIPT>
  <PUBLIC:METHOD NAME="showChildren" />
  <PUBLIC:PROPERTY NAME="iChildren" />
</PUBLIC:HTC>

HTML Component檔案的開始和結束標籤是 <PUBLIC:HTC URN="location"> 和</PUBLIC:HTC>。其中URN屬性用來替這個元件指定一個獨一無二的名稱，通常會指向HTC的放置位置。若您在同一個元件上使用多個behavior，那麼這個屬性可就很有用了。它可以和event物件的srcURN性質配合使用，來辨別各個Behavior的執行時間。

大部分的Behavior功能都可在SCRIPT區段中找到。attachEvent方法可以用來將HTC中的函式連結到某個元件的事件，而元件本身會被behavior呼叫。在我們的例子中，behavior中的toggleDisplay函式就是連結到DIV的onclick事件，因此當DIV元件被按下時，函式會切換DIV的內容，使DIV的內容可以被隱藏或被顯示，如圖22-4所示。8

圖22-4 　在Level 1 Item 1被按下之後的清單

在HTC中的SCRIPT區塊之後，我們看到兩個標籤。它們都以PUBLIC為首，好讓這段程式可以在主網頁中執行。METHOD元件將showChildren函式揭露給所在的網頁，這個函式接著會被呼叫成是一個呼叫behavior元件的方法。在程式列表22-4中，在捲簾式選單之後有兩個按鈕。當按鈕被按下時，第一個按鈕會呼叫Item1.showChildren().Item1函式。由於Item1這個DIV元件有ExpandingHead類別，因此這個類別會連結ExpMenu behavior。由於此behavior揭露了showChildren方法，因此它可以直接被當作item1物件的方法來呼叫。圖22-5展示的是最後結果的警告對話方塊。

圖 22-5 當按下第一個按鈕時顯示的警告對話方塊

在HTC的SCRIPT區段中，我們建立了一個iChildren變數，並將其值設定成那些會被HTC呼叫之網頁元件中所含子元件的數目。PROPERTY元件則是被用來當作一個網頁元件的性質來顯露這個值，在程式22-4中的第二個按鈕透過item1.iChildren來取得這個值。PROPERTY元件也可以被HTC使用，以取得在網頁上呼叫元件的性質集合。舉例來說，若一個DIV元件有一個性質FOO="Example"，下面的程式片段即可在HTC中建立一個名為FOO的變數，而此變數會連結到該DIV元件的值。

<PUBLIC:PROPERTY NAME="FOO" />9

Behavior的用處遠比這裡所介紹的要多很多，您可以在SBN Workshop網站找到更多值得參考的資料。此外，Workshop網站也提供一些behavior的範例，例如SoundRolloverbehavior，它可以應用在一個元件上，使滑鼠從此元件上方經過時會發出聲音。

預設的behavior

Internet Explorer 5包含了許多預設的behavior，以提供各種不同的網頁服務。表格22-1中只列出了一小部份。

程式列表22-5示範了saveFavorite behavior的使用。若使用者將此網頁加入到「我的最愛」資料夾，則任何saveFavorite類別的元件都會引發onsave事件。這個事件會使得程式列表22-5中的文字欄去呼叫behavior的SetAttribute方法，然後以txt1_save為名稱，儲存txt1的欄位值。當使用者選擇「我的最愛」項目後，以再次載入那個網頁時，將會觸發文字欄的onload事件，而behavior的getAttribute方法則會被用來存取儲存的設定值。

表22-1　Internet Explorer預設的Behavior
名稱 | 說明10
clinetCaps | 包括前端使用者所使用瀏覽器的相關資訊(CLIENT CAPabilitieS)
download | 允許一個檔案被下載並可以透過腳本語言來存取；此外允許下載的同時，還可以執行另一個函式
homePage | 允許您檢查及設定使用者的首頁(必須得到使用者的同意)
saveFavorite11 | 當網頁被加入使用者的「我的最愛」資料夾時，允許您控制和儲存網頁的狀態
saveHistory | 當使用者準備瀏覽其它網頁時，允許您控制和儲存目前正在瀏覽網頁的狀態
saveSnapshot | 當使用者儲存一個網頁到磁片中時，允許您控制和儲存網頁的狀態
userData | 當使用者返回網頁時，允許資訊被儲存。此外允許比cookies更有彈性及更多的資料被儲存12
<HTML>
<HEAD>
<TITLE>Listing 22-5</TITLE>
<STYLE>
  .saveFavorite {behavior:url(#default#saveFavorite)}
</STYLE>
</HEAD>
<BODY>
Uses saveFavorite:
<INPUT ID="txt1" CLASS="saveFavorite" TYPE="text"
       onsave="this.setAttribute('txt1_save'，txt1.value)"
       onload="this.getAttribute('txt1_save')">
</BODY>
</HTML>
程式22-5

Cookie

Cookie是一種小片段的資料，這些資料會經由使用者的瀏覽器儲存到使用者的電腦中。雖然目前大多數的瀏覽器都支援cookie，不過和先前所敘述的預設behavior功能相比，cookie顯然受到比較多的限制。因為cookie的檔案大小不能超過4 Kbytes，而且還被限制有些字元是不能使用的。

cookie可透過document物件的cookie屬性來存取。一般說來，cookie內所儲存的資訊會以 "名稱=設定值 (name=value) " 的形式存在。Cookie還可以存取其他多種資料型態，包括：網域、路徑、安全設定及cookie的過期時間(expiration date)資訊。下面這行script展示了如何在cookie中儲存一個變數和一個過期時間：

document.cookie="myGreeting=Hi; expires=Mon, 31 Dec 1999 23:59:59 UTC;"

在上面的程式片段中，名為myGreeting的變數的設定值為Hi。這個cookie的過期日為千禧年的倒數最後一秒(1999年的12月31日的23:59:59)。如果沒有設定過期時間，或過期時間被設定為過去的時間，則一旦使用者結束browser應用程式，該cookie就會被刪除。程式22-6和圖22-6展示的是另一個較複雜的使用方式，包括如何從另一個cookie儲存與載入資訊，以及如何顯示一個cookie中的所有名稱與設定值。13

<HTML>
<HEAD>
<TITLE>Listing 22-6</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function setCookie(strName， strVal){
  // Store cookie info-escape strVal to ensure legal characters
  document.cookie=( strName+"=" + escape(strVal) +
                    "; expires=Mon， 31 Dec 1999 23:59:59 UTC;" )
}
function getCookie(strName){
  // Separate individual cookies， store in an array
  var aCookies=document.cookie.split("; ")
  for (var i=0 ; i<aCookies.length ; i++){
    // Separate name from value， store in array
    var aOneCookie=aCookies[i].split("=")
    // Return value if cookie name matches strName
    if (strName==aOneCookie[0]){ return unescape(aOneCookie[1])	}
  }
  // Return null if no cookie exists of that name
  return null
}
function showCookie(){
  strA=""
  var aCookies=document.cookie.split("; ")
  for (var i=0;i<aCookies.length;i++){strA+=(aCookies[i]+"\n")}
  alert(strA)
}
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="F1">
<B>Create New Cookie</B><BR>
New Cookie Name: <INPUT NAME="T1" TYPE="text"> <BR>
New Cookie Value: <INPUT NAME="T2" TYPE="text">
<INPUT TYPE="button" VALUE="Create"
       onclick="setCookie(F1.T1.value ， F1.T2.value)"> <BR><BR>
<B>Show Named Cookie</B><BR>
Name: <INPUT NAME="T3" TYPE="text">
<INPUT TYPE="button" VALUE="Show"
       onclick="alert('That cookie = '+getCookie(F1.T3.value))"> <BR><BR>
<B>Display Entire Cookie</B><BR>
<INPUT TYPE="button" VALUE="Display" onclick="showCookie()">
</FORM>
</BODY>
</HTML>
程式22-6

圖22-6 這個網頁儲存及載入cookie內的資料。這個畫面顯示的是在建立兩個新的cookie後，一旦Display鈕被按下，網頁所產生的反應

使用者可以在New Cookie Name的文字欄中鍵入一個名稱，以及在New Cookie Value的文字欄中鍵入一個值，然後按下Create鈕，即可建立一個新的cookie。這些步驟會執行setCookie函式，此函式會接受名稱與設定值，並將它們儲存成cookie。使用者可以在Name文字欄中鍵入cookie名稱，然後按下Show鈕， 即可取得一個cookie中特定 "名稱=值" 的組合資訊。這個步驟會執行getCookie函式，然後將 "名稱=值" 中的名稱分離出來，而且會將每個名稱和Name欄位的值做比較。當它找到一個符合的， 即傳回 "名稱=值" 中的值。若要顯示整個cookie的內容可以按下Display鈕即可。書附光碟中tools目錄的cookies.js檔案可以輕易地加入在任何網頁上。

HTML Applications

HTML Applications (HTAs) 是一個很酷的新技術，這個技術只有在32-bit Windows平台上的Internet Explorer 5中才支援。跟一般的網頁比較起來，HTA是外觀上及運作方式都比較像傳統應用程式的一個或一組網頁。只要將傳統的網頁附檔名由HTM或HTML變成HTA，即可建立一個最基本的HTA。如果雙按有這種附檔名的檔案，即會開啟一個類似標準應用程式的視窗，不過，這個視窗並不會有Internet Explorer的工具列和瀏覽按鈕。14

一個較進階建立HTA的方式，就是在一個HTA檔案的標頭區域中使用 <HTA:APPLICATION> 標籤，這個方法可以對於應用程式的視窗外觀做比較多的控制。下面這段程式碼即示範了 <HTA:APPLICATION> 標籤以及一些可以修改視窗外觀的屬性的使用方式。

<HTA:APPLICATION ID="oHTA"
  APPLICATIONNAME="DemoApp"
  BORDER="thick"
  CAPTION="yes"
  SHOWINTASKBAR="yes"
  SYSMENU="no"
  WINDOWSTATE="normal">
表22-2　在HTA檔案中使用的特殊屬性
名稱 | 說明
applicationName | 用來設定HTA的名稱。不管用來載入它的URL是什麼，這個名稱是設定給HTA的，並且能用來判斷HTA是否正在執行中。15
border | 設定要使用的邊框形態。設定值可以是thick (預設值)、thin、none、或dialog。
borderStyle | 設定邊框的外觀。設定值可以是normal (預設值)、complex、raised、staic、和sunken。
caption | 設定要不要顯示標題列。預設為Yes。
commandLine16 | 包含從命令列中執行HTA所需要之路徑資訊的唯讀屬性。
icon | 針對HTA所使用的URL圖示。這個圖示必須要是標準的32X32 pixel大小的ICO檔案。
maximizeButton | 設定是否要最大化按鈕，預設為Yes。
minimizeButton | 設定是否要最小化按鈕，預設為Yes。17
showInTaskbar | 設定HTA是否要在Windows的工具列中及ALT-TAB列表中顯示。預設為Yes。
singleInstance | 設定是否同時讓多個複製的應用程式在同一時間內執行，預設為No。
sysMenu | 設定是否需要系統選單(此為在標題列按右鈕時出現的選單)，預設為Yes。
version18 | 設定應用程式的版本。
windowState | 設定HTA視窗的初始大小。它可以是normal、minimize、或mazimize。

DemoApp.hta如下所示，是一個展示在圖22-7的HTA範例 (DemoApp.hta可以在書附光碟的chap22目錄中找到)。

<HTML>
<HEAD>
<TITLE>DemoApp</TITLE>
<HTA:APPLICATION ID="oHTA"
  APPLICATIONNAME="DemoApp"
  BORDER="thick"
  CAPTION="yes"
  SHOWINTASKBAR="yes"
  MAXIMIZEBUTTON="yes"
  MINIMIZEBUTTON="yes"
  WINDOWSTATE="normal">
</HEAD>
<BODY>
This is a basic HTML application.
</BODY>
</HTML>

圖22-7　一個簡單的HTML應用程式19

HTA的安全考量

HTAs擁有與傳統網頁不同的安全限制。當一個HTA第一次被下載時，使用者會被詢問是否要信任(be trusted) 此HTA。若信任，則使用者將不會被詢問是否同意使用HTA的其它功能。這個程序類似傳統的應用程式，因為當使用者安裝一個傳統應用程式之後，就會給予此應用程式完整的系統資源存取能力。

當一個HTA被下載且被同意執行後，它就允許取得許多一般都會被限制的功能。舉例來說， HTA檔案允許讀取與寫入客戶端電腦的檔案系統(file system) 及登錄資料(Registery) 。HTA也可以使用Internet Explorer的命令識別字(Command identifiers)，命令識別字可以完成很多工作，從改變一段文字的justification到使用內建的Find命令來找到文字的位置。想要了解更多命令識別字的相關資訊，您可以連至SBN Workshop網站。在書附光碟中， 請看DHTML， HTML， & CSS；DHTML References；Command identifiers。若您的HTA包含了您無法控制且並不安全的FRAME或IFRAME(舉例來說， 一個框架可能會是想要連上Internet在瀏覽資料的)，那麼您就應該強制框架遵守標準的安全限制。您可以設定FRAME或IFRAME的TRUSTED屬性值為no ，來完成這項安全設定， 例如 <IFRAME SRC="somewhereElse.htm" TRUSTED="no">。

建立頻道 (Channels)

動態頻道(Active Channel) 是以Microsoft的頻道定義格式 (Channel Definition Format；CDF) 為基礎的，它是推播 (Push) 技術的其中一項應用。CDF可以是一個包裝與傳遞內容資料的強大的工具。頻道(Channel)可以用來存取Windows桌面的頻道列 (如圖22-8所示)、Internet Explorer中的頻道目錄、更新的行事曆資料、頻道螢幕保護程式、軟體的傳送頻道、動態桌面 (Active Desktop) 元件、以及其它更多應用。使用者也可以按照它們建立的行事曆，來從不同的資料提供處 "拉回(pull)" 資料內容。

一個動態頻道只是一個用CDF (Channel Definition Format) 格式敘述的網站，跟HTML檔案一樣，CDF檔案也是由各種不同元件所組成的結構化文字，且每段文字都會包含在開始標籤 (Opening Tag) 和結束標籤 (Closing Tag) 之間。對於HTML檔案來說，開始與結束標籤是 <HTML> 和 </HTML>；那CDF呢？您可猜到它的標籤長什麼樣子了嗎？沒錯！就是 <CHANNEL> 和 </CHANNEL> 。

20
圖22-8　Windows的頻道列

程式22-7展示了一個基本CDF檔的結構。為了要對這個例子做一下實驗，您必須從書附光碟中複製整個 \Chap22\cdftest目錄到您電腦的C：硬碟中。接著從c:\cdftest目錄中雙按lst22-7.cdf來測試一下頻道。這樣將會開啟網頁，並將此頻道加入您的最愛中，在「我的最愛」中，切到Channels目錄之下，然後在這個頻道上按鈕，即可存取頻道的第二個網頁。

<?xml version="1.0"?>
<CHANNEL HREF="FILE://c:\cdftest\main.htm">
    <TITLE>Dynamic HTML in Action Test Channel</TITLE>
    <LOGO HREF="FILE://c:\cdftest\cdftest.gif" STYLE="image" />
    <LOGO HREF="FILE://c:\cdftest\cdftest.ico" STYLE="icon" />

    <ITEM HREF="FILE://c:\cdftest\page1\page1.htm">
         <TITLE>Channel test page 1</TITLE>
         <ABSTRACT>Page 1 of our channel test</ABSTRACT>
    </ITEM>
    <ITEM HREF="FILE://c:\cdftest\page2\page2.htm">
         <TITLE>Channel test page 2</TITLE>
         <ABSTRACT>Page 2 of our channel test</ABSTRACT>
    </ITEM>
</CHANNEL>

程式22-7

圖22-9　頻道的圖示會顯示在Internet Explorer的頻道目錄中
Note

在 <CHANNEL> 標籤的HREF屬性和其它所有在CDF檔案的HREF屬性需要有絕對路徑位置或完整的URLs，例如， HREF="http://www.domain.com/channel/myChannel.htm" 。相對路徑位置如 /channel/myChannel.htm在CDF檔案中是不能使用的 (例如在程式列表22-7中，我們必須使用絕對路徑c:\cdftest)。在大部分常見的情形下，這些屬性都是會參考到實際的Internet網站的。21

您可從Site Builder Network Workshop知道更多有關頻道 (包括例如離線瀏覽和CDF產生器的技術) 的相關資訊。在書附光碟中，請看Workshop (References)；Content & Component Delivery；Channel Definition Format (CDF)。

設定分級系統

很多人，特別是為人父母，都會擔心小孩子在Internet上所看到的資料內容型態。基本上，Internet是一個開放的資訊交換系統，並沒有任何內建的防護機制可控制下載到瀏覽器中的內容型態。為了幫助處理這種防護措施，全球資訊網協會(World Wide Web Consortium;W3C) 成立了一個Platform for Internet Content Selection (PICS) 團體。按照W3C，"PICS是一個關於Internet資料內容標籤 (metadata即描述資料的資料) 的基礎建設。它原本就是設計用來幫助父母和老師，控制孩子可由Internet取得何種資料，但是它也可以讓標籤提供其它的用處，包括程式碼的簽名和保密隱私" (若想取得更多有關PICS建議案的資訊， 請參考W3C PICS網站 www.w3.org/PICS )。

PICS建議案由兩個規格所組成：一個是用來建立分級系統(Ratings System)，另一個則是用來建立分級標籤。第一個規格允許建立多個類別的分級系統。這個方式是相對於Motion Picture Assocation of America (MPAA) 分級系統所建立的， 不過MPAA只有一個分類，其中只包含五個值G、PG、PG-13、R和NC-17。PICS屬性並沒有定義一個分級系統，但是它提供了一種可以用來定義這種系統的語言。

實際的分級資訊使用的是一種分級標籤的型式。標籤可以顯示為：HTML文件標頭的一部分、或是另一個網站的一部份、或只是瀏覽器被告知來尋找該標籤的有關任何部分。分級的敘述行由類別和值這對屬性組合而成，這對數值反映在網頁中內容的性質，正如同下面程式中 <META> 標籤中最後一行所展示的：22

<HEAD>
<META http-equiv="PICS-label" content='
  (PICS-1.1 http://www.rsac.org/ratingsv01.html
  1 gen false comment "RSACi North America Server" for
  "http://www.myawesomelycoolwebsite.com" on "1998.11.07T17:38-0800"
  r (n 0 s 0 v l 1 2))'>
</HEAD>

PICS方法是透過比對標籤和對應的分級系統是否相符的方式來運作，目前已經有許多可以用的分級系統。舉例來說， Recreation Software Advisory Council擁有RSACi分級系統，這在Internet Explorer和MicroSystem的Cyber Patrol Software中都被支援。RSACi系統提供4種不同類型，包括：暴力(Violence)、裸體(Nudity)、性(Sex)、和語言(Language) (在分級系統中以第一個字母縮寫)，而每一個類型底下都有5種不同的層級。SurfWatch目前也已經建立另一個被其它產品所使用的不同系統，例如迪吉多 (Digital) 公司的AltaVista網頁搜尋引擎。

圖22-10展示的是一個系統的分級設定，這是在Internet Explorer中「Internet選項」的「內容警告器」的設定，為人父母可以用來設定家用電腦中可存取資料的層級。若小孩 (或任何使用電腦的人) 試著進入一個包含分級禁止的區域，它們將會被限制或拒絕存取該網頁。

圖22-10 Internet Explorer中「Internet選項」中的「內容警告器」建議使用者限制讀取有爭議的內容之網頁

當然，分級系統只有在內容提供者使用它們時才能運作。若想要得到更多有關透過RSACi或SurfWatch系統來將網頁內容分級的相關資訊，請直接連結它們的網站： www.rasc.org23 和 http://www.surfwatch.com/ 。

本章包含了許多有助於設計創意網頁的有趣技術。其中有些技術可以用在多種瀏覽器上，其它則可能只支援最新版本的Internet Explorer。下一章將探討在建立跨瀏覽器的網頁以及需要使用特定瀏覽器的技術時，如何讓網頁可以在各種瀏覽器中正常顯示。

實戰Dynamic HTML網站技術 視窗縮放
額外新技術


實戰Dynamic HTML網站技術=>跨瀏覽器和平台的網頁

跨瀏覽器和平台的網頁
小
工
具 加入書架
加入書籤
上一章
下一章

Web是一個變化迅速的環境，例如時常推陳出新的瀏覽器 (通常也視為「客戶端的使用者介面」 ) 就是最好的說明。基本上，在每一個新版本中，瀏覽器都會加入一些舊版本或其它瀏覽器中沒有支援的新功能。不過，並不是所有的新功能都能適用於所有的作業系統 (或稱為OS或平台)。因為其中部份功能可能是由特定作業系統的內建功能所提供的；而有些功能則基於經濟效益的考量，因此瀏覽器的開發公司並不會花費太多的時間、心力來設計成可支援多種平台的版本。此外，在某些情形下，瀏覽器的部份功能是為了在特定平台上支援特定用途而設計的，所以也不會被所有瀏覽器支援。

本章將涵蓋了一些可讓網站被多種瀏覽器讀取的技巧。在文章一開始的時候，我們將說明不同瀏覽器之間的一些明顯差異；然後，我們將會檢視一些讓網頁能在多種瀏覽器之間相容的方式；最後，要探討的則是一些跨瀏覽器上的常見問題及其解決方案。

瀏覽器的常見問題

在這一節中，我們將會介紹一些目前在Web上常見的瀏覽器，並且討論一下它們之間的不同。1

各種不同的瀏覽器

以下是一些使用者常用來存取網頁的瀏覽器：

  • 目前最新的瀏覽器。例如Microsoft Internet Explorer 5和Netscape Navigator。
  • 較舊版本的Internet Explorer和Netscape Navigator。不過，這些版本可能不支援框架、串接式樣式表 (CSS)、和腳本語言 (scripting) …功能。
  • 在非Microsoft Windows環境中使用的瀏覽器。(Netscape Navigator和Internet Explorer在Windows中的功能比在Macintosh或Unix中多)。
  • 純文字的瀏覽器。例如：Lynx及專為盲人設計的瀏覽器。
  • 特殊用途的瀏覽器。例如Opera減少對一些功能的支援來增加執行速度，且盡量支援最新的技術。2
  • Web crawlers將一個網站做成索引，以供搜尋引擎之用或複製一個網站的內容。

基本上，這些瀏覽器的使用介面都不一樣。

功能支援

由於Web的發展，才會有Web瀏覽器的出現。而在這幾年來，新的瀏覽器標準和一些特殊的功能不斷地被提出，不過這些標準或功能往往只能被少數的瀏覽器所支援，或是只有部份為瀏覽器支援。而在那些不支援的瀏覽器中，若想執行這些標準或功能，則很有可能會產生錯誤。此外，一個標準也有可能是一個被公認的問題，但就是故意不被支援。總而言之，網頁技術很少有完全被所有瀏覽器所支援的。表格23-1探討的就是一些在常見的瀏覽器中 (Internet Explorer和Netscape Navigator) 已經被廣泛支援的特性。

表23-1　跨瀏覽器所支援的共同功能
功能 | 說明3
框架 | 在版本3之後的瀏覽器中完全支援
HTML 3.2 | 在版本3之後的瀏覽器中完全支援，雖然在版本2的瀏覽器中只提供部分的支援。此外，HTML 3.2也定義了對於表格和許多其它一般HTML工具的支援
HTML 4.0 | 在Internet Explorer 4中有不錯的支援，而在Netscape 4中則沒有。不過兩種瀏覽器在最新的版本中都有比較完整的支援。HTML 4.0定義了框架、新標籤、和新屬性等標準，例如TITLE屬性可允許在所有元件上出現蹦現 (Pop-up) 文字，不過此屬性目前只有Internet Explorer支援， Netscape則尚未支援。
CSS4 | Internet Explorer從3.0版本開始支援，而Netscape則是在4.0以後才開始支援。Internet Explorer 4和之後的新版本對CSS都提供了更多的支援。由於不同瀏覽器對於CSS (特別是Internet Explorer 3) 有不同的支援，因此有時會發生一些執行上的錯誤。Opera 3.5及其更新的版本也提供了不錯的支援。據消息指出，未來的Netscape 5將會大幅提昇對CSS的支援。
JavaScript | 在Netscape Navigator 2中第一次被支援， 接著是Internet Explorer 3。JavaScript後來的一些改變使得跨瀏覽器的script面臨了許多挑戰。不過，在Internet Explorer 4.0和Navigator 4.06中引入的ECMA-262標準將有助於減少這些問題的發生。
Java | 在版本3.0之前的瀏覽器中的支援度已不可得知。不過，隨著瀏覽器的演進，Java也跟著改進。
物件模型 | 在所有瀏覽器中所支援的變數。事實上，從瀏覽網頁開始，物件模型就已經在作用了。版本3以後的瀏覽器比之前的版本有更多的支援。版本4的Internet Explorer瀏覽器擴展了物件模型，此模型幾乎允許所有的網頁元件被存取和改變。W3C DOM規格應該有助於讓瀏覽器之間有一個標準化的物件模型。Scott Isacc的物件模型工具DHTMLLib (本章稍後解釋) 有助於讓這些不同的支援可以比較容易被處理。5
ActiveX控制項 | 在Internet Explore 3或更新版本中被支援，每個新版本都有一些小幅度的進階改變。NCompass Labs的ScriptActive plug-in可使得Netscape Navigator加入對ActiveX的部份支援。
表單 | 在版本3或更新版本的瀏覽器中有很好的支援。可惜的是，它們在每個瀏覽器物件模型中表現的並不相同。我們會在本章後續的內容中討論更多有關跨瀏覽器的資訊。

正如您所看到的，在支援許多不同標準和特性中，產生了蠻大的變化。為了儘可能地支援最新標準，而又同時兼顧各瀏覽器的支援度，在網頁上加入程式大概是很難避免的。

您該支援哪個瀏覽器和作業平台

根據某個有高流量的網站最近使用率之分析顯示，超過200個不同的客戶端瀏覽器曾經存取過該網站。這些瀏覽器包括：2.0版以後的各種Netscape Navigator和Internet Explorer版本，以及各版本之正式版釋出之前的各種beta版；除了兩大主流瀏覽器外，其它各式各樣的瀏覽器則包括：Opera、 Mosaic和Lynx，以及各種Web搜尋器。而這些不同的瀏覽器所使用的作業系統，則包括Windows 3.1到不同平台的Unix系統和不同版本的Macintosh作業系統。而這些瀏覽器之間多少會有一些明顯或細微的差異。6

儘管有那麼多不同的瀏覽器，不過，在剛剛提到的網站上，超過96% 使用的瀏覽器仍都是最新版本的Internet Explorer或Netscape Navigator。不過要記得的是，隨著網站的不同，使用瀏覽器的百分比例也會不同，甚至還會有蠻大的差距。例如，msdn.microsoft.com的使用者相較developer.netscape.com的拜訪者，或有比較多人使用Internet Explorer。而APPLE網站apple.com的開發者，則可能會更關心那些使用Macintosh機器架設的網站，而就不會在意那些用PC架設的內部網路。

基本上，網站開發者必須根據拜訪該網站的大部分使用者所用的瀏覽器類型，來決定其網站應該要支援哪個瀏覽器。如果可能的話，您應該取得一個分析了存取網站的瀏覽器類型報告 (通常是由伺服器的log紀錄檔案所做的分析)。不過不管怎麼樣，值得慶幸的是，目前已經有很多可以建立跨瀏覽器的網頁製作技巧。

建立跨瀏覽器的網頁內容

「跨瀏覽器」其實是一個相當鬆散的觀念，因為這並不表示網頁可以用所有的瀏覽器來瀏覽。真正的跨瀏覽器的網頁指的是降低網頁效果，以製作能適合各種瀏覽器瀏覽的網頁。以下有一些方法可以確保網頁內容能儘可能地在各種瀏覽器中正常呈現：

  • 共通的支援特性
  • 「向下相容」特性
  • 使用瀏覽器偵測功能，並根據偵測到的資訊，使用該瀏覽器有支援的功能7

接著，就來看看這些技巧。

使用共通的支援特性

就技術層面來看，要建立一個完全跨瀏覽器之網頁的唯一方式，就是只使用所有瀏覽器都支援的功能與特性。不過，可惜的是大部分的網頁設計者並不會想這麼做，因為他們會覺得在使用圖像或改變字型時，只使用這些簡單的功能實在有點遜。然而，如果您能堅持使用這些基本的功能，那麼，您將可以與瀏覽者的瀏覽器達到99.9% 的相容度。即使您計劃使用更進階的特性，還是有可能找到在不同瀏覽器之間都支援的一些進階功能。

堅持使用基本功能

一些在所有瀏覽器中都支援的功能，包括GIF圖像 (JPG也是幾乎廣泛的被支援)、超連結 <A> 標籤、和一些非常基本的HTML ， 例如：<P>、<B>、 <I>、 <TITLE>、 <OL>、 <LI> 等等。您可以在W3C網站 www.w3.org/MarkUp/ 找到更早以前的HTML標準。8

基本上，只要遵循HTML 3.2的標準，那麼應該幾乎所有的瀏覽器都可以支援您的網頁。由於，版本3之後的瀏覽器對於HTML 3.2標準有很好的支援，因此只要能遵循這些標準，那麼就可以提供常用標籤的支援。HTML 3.2規格不是一份不是很長的文件，建議您可以花一點時間看一下，您可以從剛剛提到的W3C網站中找到這份文件。

當您寫好一個網頁後，您可能很難知道到底自己的網頁有沒有遵循特定的規格。為了符合這個需求，有一種被稱做「測試規格」(validator) 的程式被開發出來。基本上，測試規格程式會根據一組規則，將網頁文件從頭到尾讀一次，以確定網頁是否確實遵循了規則。目前有許多測試規格程式可供使用，且可以根據HTML 3.2來檢查文件。HomeSite網頁編輯器 (可從Allarie公司網站 http://www.allaire.com/ 找到 ) 內就包含了一個測試規格程式，且已經內建在編輯器本身中，可以方便網頁編輯者在編輯網頁時，同時測試網頁的程式碼，這是一項非常有價值的功能。W3C在 validator.w3.org 中也提供了一個測試規格的服務。其它的測試規格程式則還有HTML Check (可在 www.netmechanic.com9 找到) 和Weblint (可在 www.cre.canon.co.uk/~neilb/weblint/ 找到)。

不同的支援

一些更進階的功能在不同的瀏覽器中有不同的支援方式。一個最好的例子就是：表單和表單內的元件。舉例來說，Internet Explorer允許 <INPUT>、<TEXTAREA> 和 <SELECT> 標籤用在文件的任何地方，但在Netscape Navigator內，這些標籤則需要包含在FORM元件內。另外，Internet Explorer支援 <BUTTON> 標籤，但目前的Netscape Navigator版本卻不支援。大多的網頁搜尋器都不支援從表單傳送資料，而在不同瀏覽器的不同版本中對於script程式的支援也不太相同，我們可以從程式23-1看到這些差異性，圖23-1是程式23-1的顯示結果。

<HTML>
<HEAD>
<TITLE>Listing 23-1</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function getValIE4(){ alert(F1.S1.value) }
function getValMore(){
  alert(document.F1.S1.options[document.F1.S1.selectedIndex].value)
}
function getValMost(){
  oSelect=document.F1.S1
  // Iterate through all of the OPTIONS in the SELECT
  for (var i=0;i<oSelect.options.length;i++) {
    // If this one is selected， get its value
    if (oSelect.options[i].selected==true){sVal=oSelect.options[i].value}
  }
  alert(sVal)
}
</SCRIPT>
</HEAD>
<BODY>
<HR>
<FORM NAME="F1">
<SELECT NAME="S1">
  <OPTION VALUE="1st Item">First Item
  <OPTION VALUE="2nd Item">Second Item
  <OPTION VALUE="3rd Item">Third Item
</SELECT>
<P>Click a button to display an alert box with the item chosen above<P>
<INPUT TYPE="BUTTON" onclick="getValIE4()" VALUE="IE4+ only"><BR>
<INPUT TYPE="BUTTON" onclick="getValMore()" VALUE="NS3+ and IE4+"><BR>
<INPUT TYPE="BUTTON" onclick="getValMost()" VALUE="NS3+ and IE3+"><BR>
</FORM>
</BODY>
</HTML>
程式23-110

圖23-1　每個按鈕使用不同的函數來顯示所選擇項目的值

正如您在圖23-1所看到，這個例子顯示的是一個下拉式選單和許多按鈕。當網頁中的其中一個鈕被按下時，螢幕上會出現一個警示窗，其中會顯示下拉選單目前的選取值。要注意的是在程式23-1中，三個不同的按鈕分別使用了三個不同的函數。這三個函數展示了當瀏覽器演進到更進階的版本時，其對scripting的支援度的改變。

  • getValIE4 ：這是最容易瞭解的函數。此函數使用程式碼F1.S1.value來參考在F1表單中名為S1的下拉選單中的值。基本上，這個函數相當直覺且容易使用，但很可惜的是只有Internet Explorer 4.0以後的版本才支援。因此在其它瀏覽器或Internet Explorer較早的版本中，這個函數將會產生錯誤。
  • getValMore ：這是第二個函數，很多瀏覽器都支援此函數，如Netscape Navigator 4.0和Internet Explorer 4.0以後版本。這個函數和getValIE4的處理方式不同。首先，Navigator需要使用document物件來參考到表單，也就是在參考表單時，Navigator使用的是document.F1， 而非只單純地使用F1。此外，所有SELECT元件都有options集合，它只是包含所有 <OPTION> 標籤的列表，而這些標籤包含在SELECT元件內。SELECT元件的selectedIndex屬性包含所選擇的OPTION的數字 (以零開始計算)。因此，documet.F1.S1.selectedIndex取得所選擇項目的數字。我們可以用它來和option集合配合使用，以取得在options集合中的選擇項目， 正如同下面原始碼所示:11

    document.F1.S1.options[document.F1.S1.SelctedIndex].value

    可惜的是，當選項利用這種方式被參考時，由於Internet Explorer 3並不支援value屬性，因此在Internet Explorer 3瀏覽器中，此函數結果將會產生錯誤。

  • getValMost ：這是第三個函數，只有版本3或更新版本的兩大瀏覽器中才支援之特性。兩個瀏覽器都支援OPTION元件的selected屬性，當該項目被選取，則其值為true，反之，則為false。getValMost函數利用一個迴圈巡行所有在option集合中的元件，且測試selected屬性的值是否為true。若是，則該選項的值會被紀錄在sVal變數中。在檢查所有的選項後，sVal變數的值會被顯示在一個警示窗中。所有這些功能都被我們的目標瀏覽器 (版本3與更新版本的Internet Explorer和Netscape Navigator) 所支援，雖然有點麻煩，不過這個函數設計得很成功。

這個例子展示了在所有目標瀏覽器中測試網頁程式的重要性。它也展示了限制支援的瀏覽器數目之重要性，這樣您才能了解它們的特性與限制。

Note

在程式23-1中，若使用可允許多個選項被選取的SELECT元件，那麼，我們可能會需要稍微修改一下函數，以顯示所有被選取的選項。舉例來說，在第三個函數中，我們可能會想將每個被選擇的值新增到sVal ，而非取代目前的sVal。

向下相容12

使用了一些進階特性的網頁其實還是可以在沒有支援這些特性的瀏覽器上使用，像這樣的網頁，我們就稱之為可「向下相容」的網頁。例如，CSS就具有向下相容的特性；因為一個使用了HTML 3.2外加CSS的網頁，在Netscape 4中，網頁將會正確顯示CSS所設定的樣式，不過在Netscape 3瀏覽時，網頁看起來只會是沒有設定CSS樣式的HTML網頁而已，並不會有什麼問題。Behavior也是另一個可向下相容的技術，因為不支援Behaviors的瀏覽器會直接忽略掉behavior的程式碼，而在支援behavior的瀏覽器 (例如Internet Explorer 5)，則就可以顯示其效果。

當使用不是所有瀏覽器中都支援的特性時，標準規則是用來確定您的網站並不以這項特殊功能當作主要功能的依據。舉例來說，如果網站的主要訴求對象是純文字的瀏覽器使用者，那麼您就不應該使用Macromedia Flash檔案 (只能使用圖形) 來製作網頁 。您不應該沒有仔細考慮到，在不支援DHTML的瀏覽器中，若使用動態網頁的展開式選單來做為導覽方式時，會產生什麼狀況。一般來說，您不應該在網頁中使用太特殊的功能，除非它可以在所有目標瀏覽器中被支援，或可以提供網頁一個實質上的優點。

一般來說，網頁是否具有向下相容的特性，是可以很容易辨別的，因為只要在想要支援的最低階瀏覽器中開啟網頁檔案，就可以知道問題在哪裡了。

我們也可以善用一些在某些瀏覽器中不被支援的特性。例如 <COMMENT> 標籤 (HTML 4.0規格的一部份) 可以像 <!-- .... --> 一樣不讓夾在中間的文字被顯示出來。然而，此標籤並不被Netscape Navigator 4和Internet Explorer 3之前的瀏覽器所支援。因此，下面原始碼會在這些不支援此標籤的瀏覽器中產生警告。

<COMMENT>
這個網頁是針對支援HTML 4.0的瀏覽器來設計的
如果可以的話，請升級一下。
</COMMENT>

瀏覽器偵測

簡單來說，瀏覽器偵測的功能就是偵測客戶端所使用的瀏覽器類型。網頁內可以加入一段瀏覽器偵測程式碼，如此一來，網頁即可依據瀏覽器的類型，改變其內容，好讓網頁可以正確地在瀏覽器視窗內顯示。13

大致而言，主要的瀏覽器偵測方式有兩種。第一種方法是透過瀏覽器的navigator物件獲得有關瀏覽器的資訊。例如，在利用這種方法時，您可以知道所使用之Netscape 4版本編號中的精確小數點 (例如4.05或4.06等) 是多少。另一種偵測方法則是透過測試目標瀏覽器的特殊功能，來判斷瀏覽器的類型或版本。舉例來說，若客戶端的瀏覽器具有layers物件，那麼就可以確定這個瀏覽器必定是Netscape 4或更新的版本。

使用navigator物件

navigator物件包含很多所使用瀏覽器的有用資訊。程式23-2展示的是navigator物件的一些性質，圖23-2展示的是在Internet Explorer 5中顯示此網頁的結果，而圖23-3展示的則是在Netscape 4.08中的瀏覽結果。

<HTML>
<HEAD>
<TITLE>Listing 23-2</TITLE>
</HEAD>
<BODY>
<H2>Information about the <I>navigator</I> object in this browser.</H2>
<SCRIPT LANGUAGE="JavaScript">
document.write("<BR><B>userAgent</B>="+navigator.userAgent)
document.write("<BR><B>appMinorVersion</B>="+navigator.appMinorVersion)
document.write("<BR><B>appVersion</B>="+navigator.appVersion)
document.write("<BR><B>appName</B>="+navigator.appName)
document.write("<BR><B>appCodeName</B>="+navigator.appCodeName)
document.write("<BR><B>browserLanguage</B>="+navigator.browserLanguage)
document.write("<BR><B>cookieEnabled</B>="+navigator.cookieEnabled)
document.write("<BR><B>cpuClass</B>="+navigator.cpuClass)
document.write("<BR><B>onLine</B>="+navigator.onLine)
document.write("<BR><B>platform</B>="+navigator.platform)
document.write("<BR><B>systemLanguage</B>="+navigator.systemLanguage)
document.write("<BR><B>userLanguage</B>="+navigator.userLanguage)
</SCRIPT>
</BODY>
</HTML>
程式23-2

圖23-2　navigator物件在Internet Explorer 5中的一些屬性14

圖23-3　同樣的網頁用Netscape Navigator 4.08瀏覽的結果

navigator物件包含了許多有用的屬性，而每一個屬性都包含所使用瀏覽器的一些資訊。其中最有用的屬性是appVersion和userAgent這兩個，因為這兩個屬性可以提供瀏覽器的名稱、版本、作業系統等資訊。表格23-2展示了不同使用的情況下，透過appVersion所取得的屬性值。

appVersion屬性中的第一個數字，可指出目前所使用的瀏覽器相當於哪一個版本的Netscape Navigator瀏覽器，而括弧內的資訊描述的則是瀏覽器的名稱 (若非Netscape) 和作業系統。由於Internet Explorer 5發行之時，最新的Netscape Navigator版本為4，因此Internet Explorer 5會傳達出4.0的appVersion屬性值。在版本編號之後，所有的Internet Explorer版本都會在appVersion屬性中包含MSIE字串。基本上，user-Agent屬性也包含了相似的資訊。Script可以透過這些屬性，來確定所使用的瀏覽器到底是哪一個，然後依據瀏覽器的功能與特性，來決定要顯示的網頁內容。程式23-3示範了瀏覽器及其版本的測試功能，並且根據測試所得的瀏覽器，來套用不同的樣式表。在圖23-4中我們可以看到瀏覽器的顯示結果。

<HTML>
<HEAD>
<TITLE>Listing 23-3</TITLE>
<SCRIPT LANGUAGE="JavaScript">/
av=navigator.appVersion
// Check if IE and if so， check version
iMSIE=parseInt(av.indexOf("MSIE"))
if (iMSIE>=1){
  // Get major version and write appropriate style
  iVer=parseInt(av.charAt(iMSIE+5))
  if (iVer==3){ sStyle = "color:blue;font:italic" }
  if (iVer==4){ sStyle = "color:blue;" }
  if (iVer>=5){ sStyle = "color:blue;font:bold" }
  document.write("<STYLE>body{"+ sStyle +"}</STYLE>")
}
// If not IE， check if it's Netscape， if so， check version
else {
  if (navigator.appName=="Netscape"){
    if (parseInt(av) >= 4){
      document.write("<STYLE>body{color:red;}</STYLE>")}
  }
}
</SCRIPT>
</HEAD>
<BODY>
This page senses the browser and uses a different style sheet for each.
<HR>
The page will be blue in Internet Explorer. In version 3 the text will
be italicized， in version 4 it will be normal， and in version 5 and
later it will be bold.
<HR>
In version 4 and later of Netscape Navigator the text is red. Prior
versions do not use style sheets and display the page as standard text.
</BODY>
</HTML>
程式23-3

15
圖23-4　根據瀏覽器的不同，這個網頁將套用不同的樣式表
表23-2　appVersion性質的設定值
瀏覽器 | 作業系統 | appVersion字串
Internet Explorer 3.02 | Windows 9516 | 2.0 (compatible; MSIE 3.02; Windows 95)
Internet Explorer 4.01 | Windows 95 | 4.0 (compatible; MSIE 4.01; Windows 95)
Internet Explorer 4.01 | Windows NT | 4.0 (compatible; MSIE 4.01; Windows NT)17
Internet Explorer 5 Beta 2 | Windows 98 | 4.0 (compatible; MSIE 5.0b2; Windows 98)
Internet Explorer 5 | Windows 98 | 4.0 (compatible; MSIE 5.0; Windows 98)
Netscape Navigator Gold18 | Macintosh System 7.5 | 3.02Gold (Macintosh; I; 68K)
Netscape Navigator 3.04 | Windows 95 | 3.04 (Win95; I)
Netscape Navigator 3.04 | Windows 9819 | 3.04 (Win95; I)
Netscape Navigator 4.08 | Windows 95 | 4.08 [en] (Win95; I; Nav)
Netscape Navigator 4.08 | Windows 98 | 4.08 [en] (Win98; I; Nav)20
Netscape Navigator 4.08 | Windows NT | 4.08 [en] (WinNT; I; Nav)

首先，indexOf方法是用來確定在appVersion屬性中是否有MSIE字串。如果有，則表示瀏覽器一定是某一版本的Internet Explorer。接著，程式會取得瀏覽器的主要版本，也就是出現在MSIE後面的數字。請注意，這段程式是可以 "向上相容的"，因此若版本數字大於5，則將之視為5。

若在appVersion屬性中沒發現MSIE字串，則indexOf("MSIE") 會傳回 -1 ，且程式就會直接跳到else程式區塊中。在這裡我們利用navigator物件的appName屬性，來檢查看看瀏覽器是否為Netscape Navigator。如果是，則使用parseInt ( 請參考 第8章 有更多的資訊) 來將appVersion屬性轉換成一個主要的版本數字，這也是我們接著要測試的。若瀏覽器既不是Internet Explorer，也不是Netscape Navigator ，則if和else程式區塊都不會被執行，而且網頁也不會套用任何樣式。21

為了使瀏覽器偵測更容易，下列的script檔案可以在書附光碟中chap23\sniffer.js找到。基本上，sniffer.js檔案是一個一般的瀏覽器測試程式，它使用布林代數來保留有關瀏覽器被使用的資訊。您可以直接複製檔案中的文字到自己的網頁中，或者也可以直接將 .js檔案加入網頁中 (使用方法在 第6章 有談到)。

<SCRIPT LANGUAGE="JavaScript">
<!--
// This script checks browser being used and its version
var bIE=false， bIE5=false， bIE5=false， bIE4=false， bIE3=false， bIE2=false
var bNS=false， bNS4=false， bNS3=false， bNS2=false

av=navigator.appVersion;
// Check if Internet Explorer and if so， check version
iMSIE=parseInt( av.indexOf("MSIE") )
if ( iMSIE >= 1 ){
  bIE = true;
  if ( parseInt( av.charAt(iMSIE + 5) ) == 3 ){ bIE3=true }
  else if ( parseInt( av.charAt(iMSIE + 5) ) == 4 ){ bIE4 = true }
  else if ( parseInt( av.charAt(iMSIE + 5) ) >= 5 ){ bIE5 = true }
}
// If not Internet Explorer， check if it's Netscape， if so， check version
else {
  if ( navigator.appName == "Netscape" ){
    bNS = true;
    if (parseInt(av) >= 4){ bNS4 = true }
    else if ( parseInt(av) >= 3 ){ bNS3 = true }
    else { bNS2 = true }
  }
}

目前在網路上有許多功能很完整的瀏覽器偵測程式，提供了比一般陽春版本的偵測程式更多的詳細資訊，包括版本的小數點和作業系統資訊等。您可以在 developer.netscape.com/docs/examples/javascript/browser_type.html 和在SBN Workshop網站找到這一類的參考資料。在書附光碟中，請到Workshop (References)；Web Content Management ; sniffering for Browser，VM & OS。若想要取得線上版本，可拜訪MSDN線上資源網站22 msdn.microsoft.com/resources/schurmdhtml.htm ，或開啟書附光碟的MSDN_OL.htm檔案，然後選擇Browser Detection。

偵測瀏覽器的功能

一般來說，知道瀏覽器有哪些功能會比知道瀏覽器的精確版本要來得有用。畢竟，知道瀏覽器能執行哪些功能，會比知道瀏覽器的版本編號要來得有用得多。例如，目前有支援document.all集合的瀏覽器只有Internet Explorer 4和更新版本而已。一些可供測試的有用物件包括：

document.all Internet Explorer 4和更新版本

window.Event Netscape Navigator 4和更新版本 ( Internet Explorer的版本 是window.event)

document.images Internet Explorer 4和更新版本和Netscape Navigator 3和更新版本23

document.layers Netscape Navigator 4和更新版本

在程式23-4中，我們可以看到當瀏覽器有images集合時，我們設定了一個叫做bImg的變數，其設定值為true。當使用者的滑鼠在網頁上的圖像上移動時，事件處理程式會測試bImg的值是否為true；若是，則改變該圖像。在這個例子中， 我們並不介意使用哪個瀏覽器， 只要瀏覽器支援images集合就可以了。在書附光碟中crossplat資料夾中的IENSSwap.htm檔案中有這個檔案擴展後的版本，您可以用它來處理一般圖像轉換的工作。

<HTML>
<HEAD>
<TITLE>Listing 23-4</TITLE>
<SCRIPT LANGUAGE="JavaScript">
if (document.images) { var bImg=true }
</SCRIPT>
</HEAD>
<BODY>
<BODY>
<A HREF="http://www.microsoft.com"
  onmouseover="if (bImg){document['Img1'].src='2.gif'}"
  onmouseout="if (bImg){document['Img1'].src='1.gif'}"
><IMG NAME="Img1" SRC="1.gif" BORDER="0"></A>
</BODY>
</HTML>
程式23-4

條件註解

條件式的註解是Internet Explorer 5的一項新特性，其本質可以說是一種新型態的註解，根據所使用的瀏覽器是否為Internet Explorer 5，再決定是否要顯示註解。條件註解是瀏覽器內建的功能，並不需要載入script引擎，這意味著整個網頁的下載速度將會更快一些。下面的例子示範了條件式註解功能：

<!--[If IE 5]>
這段文字只會在Internet Explorer 5中顯示，其它瀏覽器不會顯示，因為它
包含在傳統的註解標籤中
<![endif] -->
<![if ! IE 5]>
這段文字不是包含在傳統的註解標籤中，除了在Internet Explorer 5不會顯
示外，在其它瀏覽器中會被顯示出來
<![endif]>24

注意第一段的程式碼是傳統的註解標籤中 (利用粗體顯示)。這段文字在大部分的瀏覽器中並不會顯示出來。但是如果瀏覽器是Internet Explorer 5，那麼Internet Explorer 5就會深入註解標籤，然後讀取 [ if IE 5 ] 測試。由於瀏覽器是Internet Explorer 5，因此註解內容將會被顯示。而由於下一段的文字並不是一般傳統的註解標籤，因此一般的瀏覽器將會直接顯示這段文字。但由於Internet Explorer 5會先讀取 [if ! IE 5]，並判斷出條件不成立，因此這段文字就不會在Internet Explorer 5中顯示。

在這本書的寫作期間，條件式註解仍處於非常基本的開發階段。不過，因為這個功能可以讓您決定是否只用Internet Explorer 5當作唯一可瀏覽您網頁的瀏覽器，因此預計在未來，這個特性將會是很有用的。

條件編譯

條件編輯是Internet Explorer 4的一項新技術。它可以用來進行許多使用者環境性質的簡單測試，包括客戶端的作業系統和CPU的類型。表格23-3列出的是它所支援的變數。

表23-3　條件式編譯所支援的變數
變數 | 說明25
@_win32 | 若作業系統為Win32的作業系統 (Windows 95及以後版本， Windows NT，或Windows 2000及以後版本)，則為true
@_win16 | 若作業系統為Win16-based (Windows 3.x) ，則為true
@_mac | 若作業系統為Apple的Mac OS ，則為true
@_x8626 | 若使用Intel相容處理器 (486， Pentium、Pentium II、Pentium III等) ，則為true
@_alpha | 若使用Alpha處理器 ，則為true
@_mc680x0 | 若使用Motorola 680x0處理器 (可在舊型的Macintosh相容機器中找到) ，則為true
@_PowerPC | 若使用PowerPC處理器 (可在新型的Macintosh相容機器中找到) ，則為true27
@_jscript | 永遠傳回true
@_jscript_build | 保留JScript scripting引擎的建置編號
@_jscript_version | 保留JScript引擎的版本編號

條件式編譯一開始是利用 @cc_on敘述啟動的，只要 @cc_on被啟動，@if， @elif， @else， 和 @end等條件式敘述就可以一起用來測試上表所列的變數狀態。@set敘述可以用來建立您自己的變數，例如 @set @var1=12345。請注意，最好將條件式編譯程式碼放到JavaScript的註解區 (在 /* .... */ 之間)，如此才能避免這段程式碼在其它不支援的瀏覽器中不會引發問題。程式23-5展示的是一個基本註解編輯的使用。28

<HTML>
<HEAD>
<TITLE>Listing 23-5</TITLE>
<SCRIPT LANGUAGE="JavaScript">
/*@cc_on @*/
/*@if (@_win16)
    alert("You should consider upgrading your operating system.");
  @elif (@_mac)
    alert("You are using a Macintosh.");
  @elif (@_win32)
    alert("You are using a Win32 based operating system.");
  @else
@*/
    alert("Not using Internet Explorer on a Macintosh or on Windows.");
/*@end @*/
</SCRIPT>
</HEAD>
</HTML>
程式23-5

客戶端資訊

客戶端資訊 (Client Capabilities) 是包含在Internet Explorer 5的一個預設behavior，它可以提供有關使用者系統的詳盡資訊。一些可提供的資料包括：使用者顯示器的高度、寬度和可支援的顏色數目；處理器的類型、作業系統、以及系統所連接的網路類型；是否接受cookie；是否可使用Java、以及系統所安裝的Java版本為何；另外還有瀏覽器所使用的語言。這個behavior也提供一些方法，包括組成元件的管理技術，例如測試某個特定的元件是否已安裝、及系統已安裝的元件、比較版本中的數字與其它功能。客戶端資訊behavior還有許多實作方法。請參考SBN Workshop網站或書附光碟。在光碟中， 選擇DHTML， HTML & CSS; DHTML Behaviors; Default Behaviors Refrence， 且在右邊框架中按Behaviors選項。若想要取得線上版本， 請拜訪MSDN線上資料網站 msdn.microsoft.com/resources/schurmandhtml.htm 或開啟書附光碟中的MSDN_OL.htm， 選擇Client Capabilities。程式23-6展示傳回的客戶端資訊的各項數值， 圖23-5顯示的是瀏覽器的瀏覽結果。

<HTML>
<HEAD>
<TITLE>Listing 23-6</TITLE>
</HEAD>
<BODY>
<IE:clientCaps ID="oClientCaps" />
Client Capabilities properties on this system.
<PRE>
<SCRIPT LANGUAGE="JavaScript">
oClientCaps.style.behavior = "url(#default#clientCaps)";

document.writeln("width          = "+oClientCaps.width)
document.writeln("height         = "+oClientCaps.height)
document.writeln("availHeight    = "+oClientCaps.availHeight)
document.writeln("availWidth     = "+oClientCaps.availWidth)
document.writeln("bufferDepth    = "+oClientCaps.bufferDepth)
document.writeln("colorDepth     = "+oClientCaps.colorDepth)
document.writeln("connectionType = "+oClientCaps.connectionType)
document.writeln("platform       = "+oClientCaps.platform)
document.writeln("cpuClass       = "+oClientCaps.cpuClass)
document.writeln("cookieEnabled  = "+oClientCaps.cookieEnabled)
document.writeln("javaEnabled    = "+oClientCaps.javaEnabled)
document.writeln("systemLanguage = "+oClientCaps.systemLanguage)
document.writeln("userLanguage   = "+oClientCaps.userLanguage)
</SCRIPT>
</PRE>
</BODY>
</HTML>29
程式23-6

圖23-5　這個網頁顯示一些不同的系統設定

共同的問題

瀏覽器的不同之處實在有太多主題範圍可以討論，它讓網頁開發者疲於奔命地去花時間尋找。這一段我們試著討論一些最常見的問題，以縮小問題的範圍。

同一個網頁上的BODY和FRAMESET

HTML 4.0規格中限制一個文件內只能有一個FRAMESET或一個BODY元件，但兩者不能同時存在 (除非針對不支援frames的瀏覽器， 將BODY元件包含在NOFRAMES元件內)。Internet Explorer在版本4之前，可在同一份文件內同時支援兩者，不過在版本4以後就不再支援了。若兩者同時出現在同一個文件中，則晚出現的會被忽略。您也可以透過使用一些只能在BODY元件(例如IMG和TABLE)內才有效的元件，以附帶的方式使用BODY。30

串接式樣式表的不同

很可惜的，每個瀏覽器對於串接式樣式表的實際執行方式都非常不相同。在這方面，Internet Explorer 3的問題算是最嚴重的，因為這個瀏覽器在CSS 1的正式規格制定之前就已發表了。因此，可想而知， Internet Explorer 3的實作方式自然不會符合CSS 1的標準。舉例來說， 在Internet Explorer 3並不支援em度量單位，因此em在此瀏覽器中有可能會被視為px。此外，在CSS 1規格中，要設定字型大小的百分比時，標準的方式是採用父元件的大小為基準，來設定其百分比值的；但在Internet Explorer 3中，卻會變成採用以文字的預設大小為基準，因此其結果也會和標準方式實作所得的結果不一樣。另一個例子就是在Netscape Navigator 4、Internet Explorer 3、和Internet Explorer中，CSS的繼承特性的實作方式也都不一樣。此外，在Internet Explorer 3和Netscape 4中，對於速記的屬性支援也是很零散的，而且有些功能的實行方法也並不同。

通常這種問題的最好解決方案就是在不同的瀏覽器中使用不同的樣式表，就如同本章稍早在偵測瀏覽器那段所展示的一樣。底下要介紹的這個技巧的不同點是，在所有瀏覽器中都使用同一個樣式表來處理一些共通的CSS屬性(文字顏色、大小等等)，因為這些基本的屬性在所有瀏覽器中都不會有問題。然後，在個別瀏覽器中才使用第二個特定的樣式表。另一個技巧 (若您的目標瀏覽器是不同版本的Internet Explorer，則將會十分有用) 則是利用Internet Explorer 3不支援多重樣式表或DISABLED屬性的特性 (這兩個屬性在Internet Explorer 4中都有支援) ，如下所示:

<!--Used in Internet Explorer 4 and later， not in version 3 -->
<STYLE>
   span { color : red}
</STYLE>
<!--Used in Internet Explorer 3, but
    disabled in version 4 and later -->
<STYLE DISABLED>
   span {font-size: 20pt}
</STYLE>

當目標瀏覽器是Netscape時，上面這個技巧其實並沒有什麼用處。因為Navigator 4支援多重樣式表， 但不支援DISABLED屬性，因此Navigator兩個樣式表都會使用， Internet Explorer 4和更新版本則只使用第一個，而Internet Explorer 3只會使用第二個。

不一致的物件模型

隨著瀏覽器的不同，其物件模型的差異也是很大的。舉例來說，Netscape Naviagtor並不支援像Internet Explorer 一樣的「事件沸升」。Scott Issacs (一個微軟公司的開發者兼設計者) 已經建立一個工具稱為DHTMLlib，可讓Netscape的物件模型盡量趨近於 Internet Explorer的物件模型，以克服了兩大瀏覽器物件模型的不同。此工具可以從31 www.insidedhtml/writeOnce/writeOnce.asp 下載。

視窗背景顏色

Internet Explorer 3及更早的版本和所有版本的Netscape Navigator都是使用灰色做為預設的網頁背景顏色，而Internet Explorer版本4和更新版本使用的則是白色。若您想要直接設定網頁的背景顏色，且考慮版本3或更早版本的瀏覽器，則可使用 <BODY> 標籤的BGCOLOR屬性，如下所示：

<BODY BGCOLOR="white" TEXT="black">

當設定一個很醒目的背景顏色時，那麼，設定預設的文字顏色就變得很重要了，因為您必須確保您的背景顏色不會和前景文字顏色衝突。若只考慮版本4或更新版本的瀏覽器，則可以透過background-color和color的CSS屬性來設定BODY元件中顏色。

支援不同script32

Script語言近幾年來已經有很大的進展。由於一些新特性在舊的瀏覽器中並不被支援，因此在編輯網頁時，使用最舊的瀏覽器所支援的功能來進行網頁開發的工作，將會是很實用的技巧。因為瀏覽器的功能都是可以向下相同的，因此scripts如果能在舊瀏覽器中運作，那麼也一定可以在新的瀏覽器中運作。此外， Internet Explorer 3和更新版本可以升級到最新版本的JScript引擎。您也許會想要將最新版本的scripting引擎的連結放到您網站上，您可從 msdn.microsoft.com/scripting 網站上找到這個連結位址，以方便您的使用者升級其script引擎。

在HTML解譯中有不同的彈性程度

很多網頁都沒有嚴格地遵守HTML的標準。例如下例就是一段不合法的HTML原始碼：

<P>
<H1> Heading </H1>
</P>

根據HTML規格，區塊層級的元件例如H1並不允許放到P元件的內部，因此P元件應該在H1的開始之前就結束，再者，</P> 也是多餘的。當Netscape Navigator解譯上面的原始碼時，放在BODY元件的樣式設定，將會在 </P> 之後會失效。另一個常見的例子就是Netscape Navigator 4並不能正常顯示沒有結束標籤 </TABLE> 的表格。避免這種問題最好的方法就是在將網頁發佈到web之前， 將您的HTML依照剛剛所講的方式做一下確認。33

以上只是建立跨瀏覽器的網頁時，有可能會遇到部份的問題而已。還好，目前有許多提供網頁開發技術的網站，以下是一些值得推薦的網站連結： webview.com 、 webrefrence.com 、 developer.netscape.com 、34 msdn.microsoft.com/sitebuilder 、和 http://www.w3.org/ 。

實戰Dynamic HTML網站技術 視窗縮放
跨瀏覽器和平台的網頁


實戰Dynamic HTML網站技術=>整合 Web 程式設計技巧

整合 Web 程式設計技巧
小
工
具 加入書架
加入書籤
上一章
下一章

在本書中我們介紹了許多Web程式設計的技巧。本章試圖提供一個完整的實例，將這些不同的Web程式設計技巧整合在一個範例網站中。這個用來展示的範例網站包含了一些功能，例如瀏覽器種類測試、CSS、基本的表單測試、及其它更多的功能。除此之外，我們將會指出哪些功能只能用於WWW上，而不能用於CD中。

網站的功能

這個範例網站包含以下的功能或特性：

  • 本書的一般資訊。1
  • 作者資訊。
  • 有用資源的連結。
  • 本書的電子化版本。
  • 可連到本書所有程式碼的連結。
  • 可讓使用者自訂的網頁外觀。
  • 一個在視窗左邊的DHTML展開選單 (只有在有支援的瀏覽器中才看得到)。
  • 透過一個下拉式選單來瀏覽。2
  • 網頁可以自動下載到正確的框架。
  • 支援Microsoft Internet Explorer 3.02或更新版本以及Netscape Navigator 3或更新版本。

這個範例網站使用許多特定的程式設計技巧，包括：

  • 使用框架、表格、表單、樣式表、物件模型、和cookies。
  • 跨框架使用script語言。
  • 連結到外部的CSS和JS檔案。
  • 偵測所使用的瀏覽器。3
  • 透過document.write動態改變內容。
  • 基於瀏覽器類型的動態事件處理。

    圖24-1這個範例網頁利用Internet Explorer瀏覽的結果。

    圖24-1　範例網站的首頁

網站所包含的檔案

表格24-1列出網站中用到的各個不同的HTM檔案 (它並沒有列出一些連結檔案，例如在SBN Workshop上的檔案)。表格24-2則列出這個網站中所使用到的CSS和JS檔案，也說明其用途及哪些檔案會用到它們。在兩個表格中，任何對網頁內容的參考，都是參考到main.htm，custom.htm，authors.htm，及links.htm四個檔案。4

表24-1　用來建立範例網站的HTM檔案
檔案 | 說明
default.htm | ◆ 建立主要框架的文件 ◆ 當下載一個不同的框架時，會以top框架本身重新整理 ◆ 讀取cookie5 ◆ 動態處理框架，基於一個傳遞參數(可在URL的井字符號後面找到這些參數) ◆ 包含NOSCRIPT和NOFRAMES元件來相容早期的瀏覽器
menu.htm | ◆ 建立左邊的選單框架 ◆ 可偵測所使用的瀏覽器 ◆ 建立DHTML選單、自訂事件處理程式、以及自訂瀏覽器中的樣式與類別 ◆ 透過document.all來取得文件中的各項元件6 ◆ 載入正確的框架
main.htm | ◆ 建立主要的內容框架 ◆ 使用一個表格和一個表單 ◆ 提供一個下拉式瀏覽選單
custom.htm | ◆ 允許使用者對於一些網頁的外觀與感覺做一些調整7 ◆ 使用表單 ◆ 可偵測所使用的瀏覽器，由sniffer.js所提供 ◆ 寫入一個cookie
authors.htm | ◆ 包含作者資訊
links.htm | ◆ 包含有用資源的連結8
每個內容網頁 | ◆ 使用content.css ◆ 使用legal.css來顯示版權資訊 ◆ 使用frameit.js將網頁載入正確的框架中
表24-2　用來建立範例網站的CSS和JS檔案
檔案 | 用於9 | 使用目的
cookie.js | default.htm | 允許存取cookies
custom.js | 內容網頁 | 處理自訂樣式10
frameit.js | 內容網頁 | 自動載入內容網頁到正確的框架
legal.js | 內容網頁 | 在網頁中顯示版權資訊
sniff.js11 | 如果需要 | 執行瀏覽器檢測
menu.css | menu.htm | 設定基本的選單樣式
content.css | 內容網頁12 | 設定基本樣式，與coustom.htm所設定的樣式做串接

接著，我們來深入探討這些網頁。

default.htm

default.htm是此網站的主要框架文件。就像大部分的網頁一樣，它由連結許多外部的JS Scripts開始，這些scripts都允許多個網頁同時連結使用。連結外部JS Scripts的功能在Internet Explorer 3.02或更新版本才支援，此外， Netscape Navigator 3及更新版本也支援。因此能不能支援這項功能，是設定目標瀏覽器時的最低需求。這個網頁可在書附光碟的chap24\default.htm找到，如下所示：

<HTML>
<HEAD>
<TITLE>Dynamic HTML in Action, Second Edition</TITLE>
<SCRIPT LANGUAGE="JavaScript" SRC="js/cookies.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="js/sniffer.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
//-----------------------------------------------------
// Make sure file is not hosted in a different frameset
if ( top.location.href != window.location.href )
  { top.location.href=window.location.href }

//-----------------------------------------------------
// Get any customization info about the user.
var sCookie = GetCookie("CstmStyle");
var sCstmStyle = ( ( (sCookie != null) && bVer4 ) ? sCookie : null)

//-----------------------------------------------------
// Construct the frameset. If passed a target content frame, load it.
// Otherwise, load main.htm

// Get content of URL after any #
var sPostHash=location.hash.substring(location.hash.indexOf('#')+1);

// Break up normal HTML tags to prevent premature ending of the script
sFrmStart = ("<FRAM"+"ESET COLS='200,*'><FRA" + "ME src='menu.htm'>");
if (sPostHash=="") {sFrmMain="<FRA" + "ME src='main.htm' NAME='main'>"}
else {sFrmMain = ( "<FR" + "AME src='" + sPostHash + "' NAME='main'>")}
sFrmEnd = ("</FRA"+"MESET>");
document.write(sFrmStart + sFrmMain + sFrmEnd)
</SCRIPT>
<NOSCRIPT>
<FRAMESET COLS='200,*'>
<FRAME src='menu.htm'>
<FRAME src='main.htm' NAME='main'>
</FRAMESET>
</NOSCRIPT>
<NOFRAMES>
This Web site requires a frames-capable browser.
</NOFRAMES>
</HEAD>
</HTML>

在default.htm中的兩個外部連結JS檔是cookie.js和sniffer.js。我們將會在本章稍後詳細地討論這些scripts。第一個在default.htm中很明顯可以看見的script區塊，如下所示:

//-----------------------------------------------------
// Make sure file is not hosted in a different frameset
if ( top.location.href != window.location.href )
  { top.location.href=window.location.href }13

前兩行程式碼代表的是描述此段程式用途的註解，雖然對於程式執行並非一定需要，不過這會使程式更容易被閱讀，及瞭解其用途。我們可以從註解中知道，此段程式會確保default.htm不會顯示在其他網站的框架中。網頁設計者若想要保護網頁內容，通常都會用到這個技巧。例如，新聞網站就會使用這樣的技巧，防止它們的新聞被顯示在其他公司網站的框架中。

接著的程式碼就是要執行這個動作。若視窗中top框架的URL (由top.location.href所定義) 並不符合default.htm的URL (目前視窗的位址，由window.location.href所定義 )，則直接將top框架設定成default.htm 。您可以開啟書附光碟chap24目錄中default2.htm檔案，來測試這個功能。它會試著將default.htm載入到一個子框架中，不過這是做不到的。

Note

default.htm這個檔名在WWW中是常用的檔名。許多網站伺服器中，若一個網頁有特定的檔名 (例如default.htm、default.asp、index.htm) ，且儲存在特定的目錄中，則使用者連到該URL只要以目錄名稱結束(例如 www.w3.org/Style )，則網頁會自動顯示。這個特殊檔案名稱一般都可以在伺服器軟體中設定。

下一段程式碼會讀取任何先前由此網站所儲存的cookie資訊。若cookie不是空值且使用者使用版本4以後的瀏覽器，則條件運算子 ?: 會將cookie傳回值設定給sCstmStyle；否則，cCstmStyle會被設為null。接著會建立網站的框架組，它會利用一連串的字串動態地建立，然後再利用document.write方法顯示到螢幕上。雖然這項處理有點複雜，但它可以讓我們處理一些不錯的工作。有一個網站中設定的功能，即是內容網頁會在default.htm框架之外，而放在正確的內容框架中，且可指向正確的網頁內容檔案到正確的框架中。若發生這種情況，確實下載的URL為deault.htm後面會接著井字號 (#) 且網頁的URL沒有被正常的下載。

程式碼會動態透過在井字符號後面所傳遞的值, 來重新設定frameset，且在 <FRAME> 中的SRC屬性使用這個值。若沒有這個值傳遞過來，程式碼將簡單地將SRC屬性設定成main.htm， 且建立預設的frameset。14

另一個在建立frameset中要注意的技巧，就是將組成 <FRAME> 和 <FRAMESET> 標籤的文字，切成兩個獨立的字串。瀏覽器會察覺到在字串中的HTML標籤, 且會想馬上將它們顯示出來，通常就會在Internet Explorer中發生字串沒有結束的錯誤， 而在Netscape Navigator中發生內容遺失的錯誤。有這類問題的標籤為 <SCRIPT>， </SCRIPT>，<HEAD>， </HEAD>， <BODY>， </BODY>， <HTML> 和 </HTML>。這些問題可利用將標籤切成兩個分離的字串，而此兩字串在顯示到螢幕上之前， 不會被視為標籤。<FRAME> 和 <FRAMESET>通常並不是我們上面所說的問題標籤。

在default.htm的後段為 <NOSCRIPT> 和 <NOFRAMES> 標籤。它們提供對於早期瀏覽器的相容， 若瀏覽器不支援框架和scripting語言， 則會顯示一個提示告訴使用者必須換用可使用框架的瀏覽器。

接下來我們來看兩個default.htm所使用的JS檔案。

sniffer.js

sniffer.js檔案是用來偵測使用的瀏覽器種類的。它包含了一小段script，並建立了兩個布林代數變數。第一個變數為bVer4：若瀏覽器版本大於或等於4，則bVer4設定為True。第二個變數為bDoesDHTML：若瀏覽器是Internet Explorer且版本為4或更新版本，則bDoesDHTML設定為True。第二個變數會在稍後的menu.htm中用來決定是否要建立展開選單。下面的sniffer.js檔案可以在書附光碟中chap24\js\sniffer.js找到。

//----------------------------
// This file creates a number of variables describing the browser.
var bVer4 = ( parseInt(navigator.appVersion) >= 4 )
var bDoesDHTML = ( (navigator.userAgent.indexOf("MSIE") >= 0) && bVer4)

cookies.js15

cookies.js比sniffer.js複雜許多。它包含了兩個函數：SetCookie用來寫入一個cookie；而GetCookoe則是用來讀取一個cookie。此檔案如下所列，且可以在書附光碟中chap24\js\cookie.js找到。

//----------------------------
// This JS file contains basic tools for cookie manipulation.
function SetCookie(sName,sVal,sExpires,sDomain,sPath,bSecure) {
//-------------------------------------
// Set a cookie.
  document.cookie = ( sName + "=" + escape(sVal) +
     ( (sExpires) ? "; expires=" + sExpires : "" ) +
     ( (sDomain) ? "; domain=" + sDomain : "" ) +
     ( (sPath) ? "; path=" + sPath : "" ) +
     ( (bSecure) ? "; secure" : "" )    );
}

function GetCookie(sName){
//-------------------------------------
// Traverse the cookie, looking for the passed cookie name.
// If found, return the value, else return null.
  var sDelimName   = ( sName + "=" );
  var iNameLength  = sDelimName.length;
  var iCookieLength= document.cookie.length;
  var iNameStart = 0;
  while (iNameStart < iCookieLength){
    var iNameEnd = (iNameStart + iNameLength);
    if (document.cookie.substring(iNameStart, iNameEnd) == sDelimName){
      // If name found, get the associated value.
      // (from iNameEnd  to next ; or end of cookie)
      var iValueEnd = document.cookie.indexOf (";", iNameEnd);
      if (iValueEnd == -1){ iValueEnd = document.cookie.length }
      return unescape(document.cookie.substring(iNameEnd, iValueEnd));
    }
    iNameStart = ( document.cookie.indexOf(" ", iNameStart) + 1 );
    if (iNameStart == 0) break;
  }
  return null;
}

SetCookie函式是非常直覺的，custom.htm使用了這個函式。它擁有6個引數，前面兩個引數 (sName和sVal) 是一定要設定的。這些引數是用來設定Cookie的參數，其中sName是Cookie的名稱、sVal是其設定值、sExpires是過期時間、sDomain和sPath是群組與路徑、而bSecure則是用來決定cookie是否只能夠透過保全連接進行存取動作。每個變數都以s開頭，表示此變數為字串 (String)；如果變數以b開頭，則代表其內容為布林代數值(Boolean)，例如，bSecure。若任何選項引數為空白字串或null，則此引數不會被使用。此外，cookie的值利用escape方法，來確保它不會包含任何有問題的字元。

接下來的GetCookie函數則有點複雜了。它將被傳回的cookie名稱當作它唯一的引數，因為一個cookie其實就是一個長的字串。這個函數使用許多字串處理工具來完成這個目標。基本上，它會針對整個cookie字串一個接一個字元地逐步找出想要取得值的名稱。當找到名稱時，它會將跟隨在後面的文字取出，直到遇到下一個分號(分號通常用於標示cookie name=value這組設定的結束) 或檔案的結束處。取出的文字即是cookie的相對設定值。萬一都找不到名稱，則會傳回Null值。

Note

許多cookie傳回函式會用split方法來切割由cookie傳回的字串。這個處理方式比cookie.js用的方法還簡單，不過早期的瀏覽器並不支援，包括Internet Explorer 3。

main.htm

main.htm是在此網站中主要的內容網頁，它以兩個外部連結的script檔案(frameit.js和custom.js) 作為開頭。除此之外，legal.js則是在網頁的結束時使用。下面所列的main.htm可在書附光碟的chap24\main.htm找到。16

<HTML>
<HEAD>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="css/content.css">
<SCRIPT LANGUAGE="JavaScript" SRC="js/frameit.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="js/custom.js"></SCRIPT>
</HEAD>
<BODY>
<TABLE CELLSPACING="0" CELLPADDING="0">
  <TR>
    <TD ALIGN="CENTER">
      <IMG SRC="img/book.jpg" WIDTH="104" HEIGHT="130"
           ALT="Book Cover Image" BORDER="1" ALIGN="LEFT">
      <H2>Dynamic HTML in Action, Second Edition</H2>
      <FORM>
      <SELECT onchange="var sVal=this.options[this.selectedIndex].value;
                        if (sVal != '-'){window.location.href=sVal}
                        else{this.selectedIndex=0;return false}">
        <OPTION VALUE="-">Select a Destination
        <OPTION VALUE="-">--------------------
        <OPTION VALUE="../sitebuilder/default.htm">SBN Home
        <OPTION VALUE="../workshop/default.htm">SBN Workshop
        <OPTION VALUE="../Gallery/default.htm">SBN Gallery
        <OPTION VALUE="../tools/">Tools
        <OPTION VALUE="authors.htm">About the Authors
        <OPTION VALUE="links.htm">Links
        <OPTION VALUE="custom.htm">Customize
      </SELECT>
      </FORM>
    </TD>
  </TR>
  <TR>
    <TD>
      <P>Welcome to the home page for
      <I>Dynamic HTML in Action, Second Edition</I>.
      <P>This site gives you access to many of the resources mentioned in
      the book. From here you can see the sample files for each chapter,
      get quick access to some of the tools we discuss, view the Site
      Builder Network Workshop, and even find out more about the authors.
      Click on an item in the Table of Contents on the left and enjoy!
    </TD>
  </TR>
</TABLE>
<SCRIPT LANGUAGE="JavaScript" SRC="js/legal.js"></SCRIPT>
</BODY>
</HTML>

main.htm中最有趣的功能之一就是可以使用下拉式列視窗來瀏覽網頁。當使用者在拉下選單並選擇其中一個項目時 (而非選擇最上面的選項或分隔線)，瀏覽器會自動載入被選擇之網頁。

所有這些功能都是由SELECT元件之onchange事件處理程式所完成的。當選擇其中一個選項，選項的值會利用sVal = this.options[this.selectedIndex].value這行程式，將設定值設定給sVal(請看第23章有此段程式的解說) 。若使用者選擇分隔線，則sVal會被設定成dash字元 (-)，而且SELECT元件會利用this.selectIndex=0這行程式碼來設定顯示清單中的第一個項目。在其它的狀況下，視窗會直接瀏覽被選擇的項目。

frameit.js

frameit.js使用於此網站的內容網頁。當任何連結到frameit.js的網頁載入正確框架以外的內容，則script會將default.htm載入，並且傳遞被載入的錯誤檔案名稱。在許多情況下，這種方式是十分有用的。舉例來說，一個由搜尋引擎傳回的網頁連結，通常都會自行開啟另一個視窗以載入網頁。像frameit.js的script程式就可以確保網頁會載入範例網站的框架中。下列的frameit.js可在書附光碟中chap24\js\frameit.js找到。

//---------------------------------------------------------------
// This script should be included in files destined for the main frame.
// It ensures the file appears in the proper frameset if loaded by itself.

sLoc=window.location.href;
if (top.location.href==sLoc){
  //-------------------------------------------------------------
  // Retrieve file name only-NS3 does not allow "file://" in URL
  iLastBack = sLoc.lastIndexOf('\\');
  iLastForw = sLoc.lastIndexOf('/');
  iLastSlash=( (iLastForw > iLastBack) ? iLastForw : iLastBack );
  sFName = sLoc.substring(iLastSlash+1);

  //-------------------------------------------------------------
  // Navigate to default.htm and pass it the name of the current file.
  top.location.href="default.htm#"+sFName;
}

只有當top.location.href相當於window.location.href時 (當目前網頁並不包含在任何框架時成立)，此script才會被啟動。若是如此，script會將目前的URL最後面的斜線或反斜線之後的名稱取出來。然後瀏覽器會指向一個新的URL，包含default.htm 、和一個井字號 (#)、以及剛剛找到的目前內容網頁名稱。井字號一般用來設定書籤，但是在此，其作用是用來傳遞參數給HTML網頁。在井字號後的URL內容可以利用location.hash屬性來取得。一個相似且有用的屬性是location.search，它會傳回任何在URL中問號後面的文字。17

legal.js

很多網頁擁有一些元件可使用在網站中的大多數網頁中。一個常見的例子就是在每個網頁底部的版權說明 (legal notice)。legal.js是一個簡單的檔案，可用來維護所有網頁底部的版權說明文字。當版權說明需要更新，您只需改變legal.js的文字，而不需更改所有網頁。同樣的技巧也可以用在其它的網頁內容上，例如，瀏覽工具列或廣告看板。這個技巧的另一個好處是，只要JS檔案沒有被更新，則客戶端的cache中就會一直存在這個檔案，除非檔案被更新，才會重新下載。因為不是每個網頁都得重新下載，因此網站的瀏覽效率將會提高不少。下面的legal.js檔案可在書附光碟chap24\js\legal.js中找到。

//----------------------------
// This file writes a copyright notice to the page.
sCpy=("<P><FONT SIZE='-1'>"+
      "©1999 Eric M. Schurman and William J. Pardi. "+
      "All rights reserved.</FONT>")
document.write(sCpy)
Note

為了在眾多網頁上使用相同的內容，一般也時常利用Server端而非client的技術，例如Server-side includes。大部分的網頁伺服器都支援一個功能，那就是在網頁中產生一個指向伺服器中另一檔案的連結，而這個檔案會加入此連結位置。這個技術的好處就是不需要在客戶端設定任何的scripting，只要處理送至瀏覽器的標準HTML就好了。

menu.htm

menu.htm提供網站的瀏覽方法。我們來看看這個網頁用了哪些程式碼。這個程式可以在書附光碟的chap24\menu.htm找到。

<HTML>
<HEAD>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="css/menu.css">
<TITLE>Menu</TITLE>
<SCRIPT LANGUAGE="JavaScript">
//----------------------------------------------
// If loaded by itself, load default.htm instead.
if (top.location.href == window.location.href)
  { top.location.href="default.htm" }
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="js/sniffer.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript"><!--
//-----------------------------------------------
// If browser supports this type of DHTML, hide menu items, do mouseover
// style effects and images, and make the expanding menus.
if(bDoesDHTML){
  sStyle=(".off{display:none} .on{display:block}" +
          "a:link {text-decoration:none}" +
          "a:visited {text-decoration:none}" +
          "a:hover {text-decoration:underline; color:red}" +
          "a:active {text-decoration:underline; color:red}")
  document.write("<STYLE>"+sStyle+"</STYLE>");
  window.onload=Function("MakeExpanding()");
}

function MakeExpanding(){
  //--------------------------------------
  // Add click handler to all items of class L1.
  var oDA=document.all;
  for (i in oDA){
    if (oDA[i].className=="L1"){
      oDA[i].onclick=Function("ToggleMenu(this)");
      oDA[i].href="javascript:;"
    }
  }
}

function ToggleMenu(oHead){
  var oAll=document.all;
  iIndex=oHead.sourceIndex;
  if (oAll(iIndex+4).className=="off"){
    oAll(iIndex).src="img/open.gif";
    oAll(iIndex+4).className="on";
  }
  else {
    oAll(iIndex).src="img/closed.gif";
    oAll(iIndex+4).className="off";
  }
}
//-->
</SCRIPT>
</HEAD>
<BODY LEFTMARGIN="0" TOPMARGIN="0" TEXT="black" BGCOLOR="#CCCCFF">
<CENTER><FONT SIZE="+3"><B>TOC</B></FONT></CENTER>
<TABLE CELLSPACING="0" CELLPADDING="0">
  <TR><TD><IMG SRC="img/trans.gif" WIDTH="9" HEIGHT="1"></TD>
    <TD>
      <BR><A HREF="main.htm" TARGET="main"><B>Home</B></A>
      <BR><A HREF="authors.htm" TARGET="main"><B>About the Authors</B></A>
      <BR><A HREF="links.htm" TARGET="main"><B>Useful Links</B></A>
      <BR><A HREF="../tools/" TARGET="main"><B>Tools</B></A>
      <BR><A HREF="custom.htm" TARGET="main"><B>Customize</B></A>
    </TD>
  </TR>
</TABLE>
<A CLASS="L1" TITLE="Site Builder Network" TARGET="main">
<IMG SRC="img/closed.gif" WIDTH="9" HEIGHT="9" BORDER="0"
><B>Site Builder Network</B></A><BR>
<TABLE CELLPADDING="0" CLASS="off">
  <TR><TD><IMG SRC="img/trans.gif" WIDTH="15" HEIGHT="1"></TD>
      <TD>
        <FONT SIZE="-1">
        <A HREF="../SiteBuilder/default.htm" TARGET="main">Home</A><BR>
        <A HREF="../workshop/default.htm" TARGET="main">Workshop</A><BR>
        <A HREF="../Gallery/default.htm" TARGET="main">Gallery</A><BR>
        </FONT>
    </TD>
  </TR>
</TABLE>
<A CLASS="L1" TITLE="Access to each chapter's files" TARGET="main">
<IMG SRC="img/closed.gif" WIDTH="9" HEIGHT="9" BORDER="0"
><B>Code Listings</B></A><BR>
<TABLE CELLPADDING="0" CLASS="off">
  <TR><TD><IMG SRC="img/trans.gif" WIDTH="15" HEIGHT="1"></TD>
      <TD>
        <FONT SIZE="-1">
        <A HREF="../chap01/" TARGET="main">Chapter 1</A><BR>
        <A HREF="../chap02/" TARGET="main">Chapter 2</A><BR>
        <A HREF="../chap03/" TARGET="main">Chapter 3</A><BR>
        <A HREF="../chap04/" TARGET="main">Chapter 4</A><BR>
        <A HREF="../chap06/" TARGET="main">Chapter 6</A><BR>
        <A HREF="../chap07/" TARGET="main">Chapter 7</A><BR>
        <A HREF="../chap08/" TARGET="main">Chapter 8</A><BR>
        <A HREF="../chap09/" TARGET="main">Chapter 9</A><BR>
        <A HREF="../chap10/" TARGET="main">Chapter 10</A><BR>
        <A HREF="../chap11/" TARGET="main">Chapter 11</A><BR>
        <A HREF="../chap12/" TARGET="main">Chapter 12</A><BR>
        <A HREF="../chap13/" TARGET="main">Chapter 13</A><BR>
        <A HREF="../chap14/" TARGET="main">Chapter 14</A><BR>
        <A HREF="../chap15/" TARGET="main">Chapter 15</A><BR>
        <A HREF="../chap16/" TARGET="main">Chapter 16</A><BR>
        <A HREF="../chap17/" TARGET="main">Chapter 17</A><BR>
        <A HREF="../chap18/" TARGET="main">Chapter 18</A><BR>
        <A HREF="../chap19/" TARGET="main">Chapter 19</A><BR>
        <A HREF="../chap20/" TARGET="main">Chapter 20</A><BR>
        <A HREF="../chap21/" TARGET="main">Chapter 21</A><BR>
        <A HREF="../chap22/" TARGET="main">Chapter 22</A><BR>
        <A HREF="../chap23/" TARGET="main">Chapter 23</A><BR>
        <A HREF="../chap24/" TARGET="main">Chapter 24</A><BR>
        </FONT>
    </TD>
  </TR>
</TABLE>
</BODY>
</HTML>18
Note

所有範例網站中的連結不是絕對、(指定完整的URL ) 就是相對的(指定相對於目前網站的位置) 位址。若將這些網頁真的放入網站伺服器中，我們可以使用改變後的絕對位置來指向網站上的檔案。要指定相對於網站伺服器根目錄的目錄名稱，只要在目錄名稱前面加上一個斜線即可。例如，要在microsoft.com網站上參考 microsoft.com/ie/ie.htm ，只要用HREF="/ie/ie.htm" 就可以了。另外，如果任何目錄下的網頁都要參考到一個相對於網站根目錄下的css目錄中的main.css檔案，那麼只要使用 /css/main.css路徑即可。同樣的，這種方式同樣也可以使用在SCRIPT區段連結JS檔案時使用。之所以這樣做的原因，是因為有一個很重要的好處是，即使HTML檔案任意搬移，連結也不會遺失或被切斷 (在本章我們沒用這個技巧，是因為在Netscape Navigator中，儲存在CD中的網站無法這麼用)。除此之外，大部分的網站伺服器軟體都可以建立虛擬根目錄或虛擬目錄，這些都是在目錄樹狀結構中任何層級的目錄，而它可以被設定為相對於網站伺服器root的虛擬目錄。而這些目錄也可以使用我們剛剛所講的方法來指定路徑。

因為menu.htm本身的功能並不是十分多，因此第一段script只是確定檔案是否載入正確的框架中。接下來，在載入sniffer.js時，會執行一個測試，以測試瀏覽器是否支援展開選單所需的功能，若支援，則接著會有下面兩件事情發生。

首先，會有一個新的樣式表被寫入網頁中。這個樣式表包含 .on和 .off類別，它們可以使選單顯示或消失。注意一下包含兩層選單項目的表格就有 .off類別。當這個樣式表寫入網頁時，第二層選單並沒有在網頁載入時顯示。當樣式沒有寫入到網頁時，表格會正常的顯示。此樣式也取消了連結下方預設會出現的底線，其連結形式改成當滑鼠移到連結上方時，才讓連結變成底線與反白。

下一行window.onload=Function("MakeExpanding()"); ，會在Window載入後，進行MakeExpanding函式的呼叫，這個函式將會完成展開選單該有的準備。請注意，網頁中的HTML程式碼並沒有任何事件處理程式可執行展開選單的功能。MakeExpanding函式會將需要的事件處理程式加到適當的元件中，然後利用巡行all集合並檢查網頁中所有元件的方式，來完成這項工作。若元件有類別L1 (第一層標題的連結)，則當元件被按下時，將會被指定到事件處理程式中，並呼叫ToggleMenu函式。MakeExpanding函式也會指定一個javascript: 的HREF屬性。連結若沒有HREF屬性，則會被顯示成一般文字，也就是沒有底線，也不能在上面按鈕。設定HREF屬性將可以讓連結具有被按鈕的特性。然而，因為我們不希望按下一個連結後，使得瀏覽器瀏覽到目前網站之外的網頁，所以，我們使用HREF，讓網頁不做任何動作。

一般而言，當一個HREF包含一個由http: 開始的值時，瀏覽器會瀏覽到指定的位置上；若包含由javascript: 開始的值，則瀏覽器會執行跟隨在後的程式碼。因此，<A HREF="javascript:alert('hi')"> Show Alert</A> 會產生包含文字hi的一個警示窗。這個功能在Internet Explorer 3.02或更新的版本以及Netscape Navigator 3或更新的版本中都有支援。基本上，分號在JavaScript中代表的是「不執行任何動作」的意思。因此，HREF若設為javascript:; 將會導致連結可以被按鈕，不過並不會產生任何動作。MakeExpanding函式中有一個onclick事件處理程式，此程式會處理呼叫ToggleMenu函式，來展開或收回選單。ToggleMenu函式會切換展開的項目，並關閉或將箭頭符號的方向改為向下或向右。這個函式會接受一個引數，當連結被按下時，函式會決定在all集合中項目的索引值。要被改變的圖像以及要被顯示或隱藏的表格是在索引項目後的一組數字。它們透過all集合來存取，同時，選單項目也會依照目前的狀態切換為展開或折疊。19

在menu.htm中的另一個重要技巧是，一些HTML標籤都是斷開的，如此結束字元 > 才會被放在下一行中，然後緊緊貼在下一個標籤的 < 字元之前。如果有一個換行符號或一個空格分隔了在連結內的兩個標籤或是開放 <A> 標籤的連結內容，則將會可以看到加了底線的額外空白字元。一般我們都會將兩個標籤放在同一行中，不過也不是一定要這樣。受到本書一行的長度限制，在此處，將標籤截斷換到下一行也是常見的使用方式。

custom.htm

custom.htm檔案允許使用者自訂網站內的一些網頁外觀，這個改變可以當成是cookie並存在使用的系統中，以備日後可以重複使用。此檔可在書附光碟中chap24\custom.htm找到，此網頁顯示在圖24-2。

<HTML>
<HEAD>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="/chap24/css/content.css">
<SCRIPT LANGUAGE="JavaScript" SRC="js/frameit.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="js/custom.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="js/sniffer.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
<!--
var sFontFamly = "body,td{font-family:arial;} "
var sFontColor = "body,td{color:black;} "
var sBackColor = "body,td{background-color:white;} "
function Commit(){
  if (bVer4){
    //------------------------------
    // Check to make sure style choices OK,then save.
    if ( sFontColor.substr(sFontColor.lastIndexOf(":") ) ==
         sBackColor.substr(sBackColor.lastIndexOf(":") ) ){
      alert("Please make sure the font and background colors differ.")
    }
    else{
      top.sCstmStyle=(sFontFamly+sFontColor+sBackColor);
      top.SetCookie("CstmStyle",top.sCstmStyle,
                    "Fri,31 Dec 2010 23:59:59 UTC","","","");
      location.reload();
    }
  }
  else{alert("These features require a version 4 or later browser.")}
}

function Select(oWhich,oItem){
  //------------------------------
  // If a legitimate item (not with value -) is selected,assign its
  // value to the variable passed as oWhich.
  var sItem = oItem.options[oItem.selectedIndex].value;
  if (sItem != '-'){ eval(oWhich+"=sItem") }
  else{ oItem.selectedIndex=0;return false }
}
//-->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="White" TEXT="Black">
<H1>Personalization</H1>
<P>This page allows users of version 4 and later browsers to personalize
the look and feel of many of the pages in this site. Information about
any changes made is stored in cookies.

<FORM>
<BR>Select a Font
<SELECT ONCHANGE="Select('sFontFamly',this)">
  <OPTION VALUE="body,td{font-family:arial;} ">Arial
  <OPTION VALUE="body,td{font-family:times;} ">Times
  <OPTION VALUE="body,td{font-family:courier;} ">Courier
</SELECT>
<BR>Select a Font Color
<SELECT ONCHANGE="Select('sFontColor',this)">
  <OPTION VALUE="body,td{color:black;} ">Black
  <OPTION VALUE="body,td{color:blue;} ">Blue
  <OPTION VALUE="body,td{color:red;} ">Red
  <OPTION VALUE="body,td{color:white;} ">White
</SELECT>
<BR>Select a Background Color
<SELECT ONCHANGE="Select('sBackColor',this)">
  <OPTION VALUE="body,td{background-color:white;} ">White
  <OPTION VALUE="body,td{background-color:blue;} ">Blue
  <OPTION VALUE="body,td{background-color:red;} ">Red
  <OPTION VALUE="body,td{background-color:black;} ">Black
</SELECT>
<BR><INPUT TYPE="BUTTON" VALUE="Commit Changes"
           onclick="Commit()">
<BR><INPUT TYPE="BUTTON" VALUE="Reset to Default"
           onclick="top.sCstmStyle='';location.reload()">
</FORM>
<SCRIPT LANGUAGE="JavaScript" SRC="js/legal.js"></SCRIPT>
</BODY>
</HTML>

圖24-2　這個網頁允許使用者自訂網頁樣式

當使用者選擇任一個下拉式選單中的選項時，所選擇的設定值會儲存到sFontFamily、sFontColor、或sBackColor變數中。當按下Commit Changes鈕時，Commit函式就會被執行。此函數一開始就會檢查被選擇項目的背景顏色會不會與文字顏色相衝突。若不會，則將所選的選項儲存在top框架中的變數及cookie中。接著，網頁會被重新整理。在top框架的變數會在前面加上top的前置文字以便參考。其它框架的變數則可以將top換成該框架名稱。框架名稱可以用在 <FRAME> 標籤內的NAME屬性來設定。關鍵字parent可用來參考目前框架組的上層元件，在此處的目前框架也就是top。20

cookie可以透過SetCookie函數 (此函式會被載入top框架) 的呼叫來設定。注意一下SetCookie的其中一個參數是日期，這個日期必須遵守通用座標時間 (Universal Coordinated Time; UTC) 格式。為了保證您使用一個相容於UTC的日期格式，您可使用一個JavaScript DATE物件及getUTCDate方法。

custom.js

custom.js檔案是一個非常簡單的檔案，使用於內容網頁中，可檢查看看是否已設定任何自訂的樣式。如果有，則將樣式寫入網頁中。您可以在書附光碟中chap24\js\custom.js找到這個檔案。

//----------------------------
// Write any custom style sheet specified by user.
if ( top.sCstmStyle != null ) {
  document.write("<STYLE>"+top.sCstmStyle+"</STYLE>")
}

authors.htm和links.htm

這些是簡單的網頁，沒有特別的功能。它們包含了一些HTML網頁以及一些外部連結檔案，如frameit.js、custom.js、和legal.js的HTML原始碼。

若您確實地跟著本書一步步操作，相信您現在應該已經有一些如何利用Web常用的技術，來處理一些工作的構想。從使用者與程式設計者的角度來看，瀏覽器、Web、和Internet無疑都是令人興奮的領域。未來也絕對會比過去要來得進步，而web的全球化及Intranets的普遍化相信也會獲得提升。因此不論您的興趣是建立個人網頁或複雜而功能強大的資料庫系統Intranet網站，網頁開發都應該是一個有趣且值得努力研究的領域。21

實戰Dynamic HTML網站技術 視窗縮放
整合 Web 程式設計技巧


實戰Dynamic HTML網站技術=>Appendix A 解決一些疑難雜症

Appendix A 解決一些疑難雜症
小
工
具 加入書架
加入書籤
上一章
下一章

本附錄將探討處理script、圖像、HTML時，常會遇到的一些問題。且提出一些建議來避免發生這些問題。其他額外有關web之解決疑難雜症資訊，請參考在 附錄B 所列出的各項資源與工具。

不如預期的布林敘述運算結果1

在JScript中一個常見的錯誤，特別在一個If敘述中，那就是在布林敘述中使用設定運算元 ( =，單一等號)，而不是使用相等運算元 ( ==，兩個等號)。舉例來說，假設變數a的值為4，則您可能會誤寫成如下的敘述，而產生一個警告對話方塊：

if (a=5){alert("!")}

此程式並沒有在a和5之間測試它們之間是否相同，然而相反地，它將5的值設定給a，這項敘述並不會產生false，所以永遠都會產生警示窗。

正確的敘述，如下此行所示:

if (a==5){alert("!")}

此敘述測試是否相同且產生警示窗只有當a等於5的時候。因為a等於4 ，所以並不會產生警示對話方塊。

想要複習常用在布林敘述的邏輯運算子或想要找更多有關if敘述的資訊，請參考2 第9章 。

當設定樣式沒作用時

當您使用CSS時，您可以使用兩種方法來設定屬性。在行內HTML設定和在樣式表中設定，指定的屬性名稱應該為小寫字母，有的屬性名稱由兩個字所組成，之間用連字號連接。冒號將屬性名稱與所設定的值分隔，就像下面font-style這個例子所示:

<SPAN ID="span1" STYLE="font-style: italic">

在script中，您可透過相對的Dynamic HTML物件模型屬性來存取一個CSS屬性，如在 第15章3 所說明。物件屬性名稱與CSS屬性名稱可以不同。物件屬性並不使用連字號，而在相對的CSS屬性之連字號後面的字母，在物件屬性中為大寫 (因此，font-style屬性相對於fontStyle屬性)。在script程式碼中，您必須使用相等符號來分隔物件屬性與其設定值，若設定值並非數字或變數名稱，則您必須自行將設定值加上雙引號，如下所示:

span1.style.fontStyle="italic"

若您將名稱轉換搞錯或使用了錯的分隔符號，您會發現樣式並沒有正確地被設定。舉例來說，若我們將前面那個設定斜體的例子中之雙引號刪除，我們會得到 'italic' is undefined之錯誤訊息。若使用等號代替冒號來當作分隔符號的話，也會產生另外一個錯誤。

瀏覽器不承認某元件為物件

瀏覽器有時候會出現一個錯誤訊息，告訴您在程式中的一個元件並不是物件。這項錯誤通常都是由於擁有好幾個物件取同一個名稱，或根本就沒有所指定名稱之物件。程式A-1提供一個例子。

<HTML>
<HEAD>
<TITLE>Listing A-1</TITLE>
</HEAD>
<BODY>
<SPAN ID="span1">This is a span.</SPAN>
<SPAN ID="span1">This is another span.</SPAN>
<SCRIPT LANGUAGE="JavaScript">
span1.style.fontStyle="italic"
</SCRIPT>
</BODY>
</HTML>
程式A-14

當您在Microsoft Internet Explorer中瀏覽程式A-1，因為程式中包含不只一個名稱為span1的物件。所以會出現一個 "span1.style並不是一個物件" 的錯誤訊息。結果是Internet Explorer無法決定應該改變哪個物件。當程式A-1在Netscape Navigator顯示時，communicator console (若顯示時) 會顯示span1沒有定義的錯誤。您可以在Go欄位 (就像Internet Explorer的位置列)上鍵入javascript: 即可開啟Communicator Console。當在Netscape Navigator中存取一個不存在的物件，有時候會沒有錯誤且script程式沒有作用。若您在跨瀏覽器中使用物件而發生問題時，您可能會想找一些協力廠商的工具，例如Scott Issac的DHTMLLib，您可以在 http://www.insidehtml.com/ 找到這個有用的工具。

瀏覽器需要一個引號或大括弧

當您接收到這種類型的訊息時，您會發現瀏覽器參考錯誤的那行並沒有包含任何script程式，這是因為引號或大括弧應該是要放在上一行中。舉個例子，觀看程式A-2您就會容易瞭解了。

<HTML>
<HEAD>
<TITLE>Listing A-2</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function test()
alert("This is an alert!"
//-->
</SCRIPT>
</HEAD>
</HTML>
程式A-25

程式A-2包含3個錯誤。當程式執行時，Internet Explorer會顯示一個錯誤訊息 "讀取列： 7字元：1錯誤: 需要 '{' "，而Netscape Navigator 4的Communicator Console會顯示錯誤 "錯誤列7: 在函數主體之前缺少 { "。因為第6行程式定義一個函式，它應該在一組括弧之後接上一個大括弧。在第7行瀏覽器所處理為顯示一個警示窗，在此處它也應該要有一個結束的大括弧，所以在此處也會顯示一個錯誤。

若您在修改這第一個錯誤後再次執行程式 (在那組括弧後面放置大括弧)，Internet Explorer顯示錯誤訊息 "列：9字元：1錯誤：需要 ')' 程式碼：0"，且Navigator顯示 "列9：在引數列後少了 )" 錯誤，因為alert方法缺少結束的括弧。若您修改了此項錯誤再執行一次，會產生最後一個錯誤，就是由於缺少函數結尾之大括弧的緣故。

瀏覽器告知一個定義過的物件沒定義

這個錯誤通常都是發生在物件完成下載或定義之前，就有script程式參考到此物件。您有很多方式可以來解決這個問題。您可以將script程式碼放在您想要參考到的物件之前，或您就直接將所有的script程式放置在HTML的head區塊中，但是只有當所有物件都下載後才呼叫物件。後面這個技巧通常是較受歡迎的解決方案，因為它幫您將程式組織化。建立一個當網頁完全下載後，呼叫一個函數的事件處理程式，如下所示:

window.onload=functionName;

或

window.onload=Function("functionName()");6

或只能用於Internet Explorer：

<SCRIPT FOR="window" EVENT="onload">
{The script you want run，or a call to a function}
</SCRIPT>

發生無預警的事件

在Internet Explorer中，這個問題通常都和事件沸升有關 (在 第7章 中有討論)。舉個例子，當使用者的滑鼠指標移入或移出一個表格時，您可能會想要讓一些特定事件發生。若您只是在table中加入onmouseover和onmouseout事件處理程式，表格中的儲存格上發生的事件與在整個表格所發生的事件相同，都同時會啟動這些處理程式。這是因為發生在儲存格的事件在物件模型中向上沸升，直到傳到父物件 (表格) 為止。程式A-3和圖A-1展示兩個如何運作的例子

<HTML>
<HEAD>
<TITLE>Listing A-3</TITLE>
</HEAD>
<BODY>
Notice that mousing between cells in the top table increments the
number of mouseovers and mouseouts.
<TABLE ID="A" BORDER="2"
  onmouseover="F1.MOver.value=parseInt(F1.MOver.value)+1"
  onmouseout="F1.MOut.value=parseInt(F1.MOver.value)+1">
  <TR><TD>Cell1</TD><TD></TD><TD>Cell2</TD></TR>
  <TR><TD>Cell3</TD><TD></TD><TD>Cell4</TD></TR>
</TABLE>
Notice that mousing between cells in the bottom table does not increment
the number of mouseovers and mouseouts. Only mouse events on the table as
a whole have an effect.
<TABLE ID="B" BORDER="2"
  onmouseover="if(!B.contains(event.fromElement))
                 {F1.MOver.value=parseInt(F1.MOver.value)+1}"
  onmouseout="if(!B.contains(event.toElement))
                {F1.MOut.value=parseInt(F1.MOut.value)+1}">
  <TR><TD>Cell1</TD><TD></TD><TD>Cell2</TD></TR>
  <TR><TD>Cell3</TD><TD></TD><TD>Cell4</TD></TR>
</TABLE>
<FORM ID="F1">
  Mouseovers: <INPUT ID="MOver" TYPE="text" VALUE="1">
  Mouseouts: <INPUT ID="MOut" TYPE="text" VALUE="1">
</FORM>
</BODY>
</HTML>7
程式A-3

圖A-1 當滑鼠在兩個表格上做移動時，兩者會產生不同的動作

在程式A-3的第一個表格，任何TABLE元件接收到的onmouseout事件會使得Mouseouts欄位中顯示的數值加一。不論是在TABLE元件本身或TD元件上被驅動這個事件，都會產生這項動作。若您在這個上面這個表格上移動滑鼠指標，您會發現Mouseouts和Mouseovers的欄位數值增加十分快速。

在第二個表格中，onmouseout事件處理程式會執行測試，只有當事件不是發生在表格之內，就會增加 Mouseouts欄位數值。換句話說，唯一影響onmouseout事件發生的就是TABLE本身。

Note

有些事件並沒有沸升。若您有事件沸升的疑問，請參考SBN Workshop網站或書附光碟來確定事件不沸升的問題在哪裡。在書附光碟中，請參看Workshop (References) 且選擇DHTML，HTML & CSS；DHTML References；Events。要取的線上版本，請拜訪MSDN Online資源網站 msdn.microsoft.com/resources/schurmandhtml.htm8 或在書附光碟中開啟MSDN_OL.htm檔案，然後選擇Events。

一個圖像顯示成您不想要的顏色

當一個電腦螢幕被設成 8-bit的顏色解析度，它只可以顯示256個顏色。舉例來說，當瀏覽器載入一個GIF圖形時，它會試著利用圖像所使用的顏色來顯示。若下載另一圖像使用不同的調色盤，為了兩個圖像顏色與瀏覽器的調色盤能調和，在瀏覽器的顏色會重新調色，結果有可能會產生調色不協調的現象，就算沒哪麼嚴重，圖像的顏色絕對不如預期一樣，因為可能沒有足夠顏色來顯示此兩圖像。

為了避免顏色不調和或要重新調色，圖像的調色盤應該和 "browser-safe" 調色盤相符 (包含在書附光碟的Tools目錄中)。當圖像從High color (或稱全彩或24-bit) 轉換到調色好的顏色通常都能相符。多數的圖像編輯程式允許設計者讓圖像指定一個調色盤。

網頁太大以致於不好下載

此問題一個直接的解決方案就是降低一個網頁圖像的數目。雖然這當然並非是適用於所有情況，不過它顯然是一個好的觀念，就是可以考慮看看每個圖像的使用是否必要，可否以其他元件代替。舉例來說，在還沒有動態樣式之前，許多有樣式或特殊字體的文字都只有利用將特殊文字放入圖檔的方式才能辦到。現在這種圖像就可被HTML和樣式表來取代，這樣也會顯著降低下載時間。

在Web上最常用的圖檔格式就是GIF和JPEG (附檔名分別是 .gif和 .jpg或 .jpeg )。這兩種圖檔格式使用不同的壓縮方法且因此適合用於Web環境。若您的圖像是大面積的單色系圖形，則GIF通常檔案會最小。若您的圖像包含變化較多的顏色，例如真實的照片，JPEG通常會產生最小的檔案大小且最好的品質。9

為了展示這些不同，我們儲存兩個圖檔利用個別最佳化的圖檔格式。您可在書附光碟中的appxA目錄看到這些圖檔。第一個檔案spots.gif，檔案大小少於3 KB，且圖像就像它在螢幕上看到的一樣。第二個檔案，clounds.jpg，為15KB，此圖像的顏色很柔且光亮。現在來看看一樣的圖像用不同格式儲存會如何。

雖然spots.jpg看起來還不錯，不過檔案大小現在變成30 KB，是GIF格式的13倍大。 clouds.gif檔案則是從15 KB的JPG格式驟增到160 KB，您可以看到色階嚴重的被降低且顆粒很大。所以值得測試一下您不同格式的圖像。

使用Structured Graphics控制項 (在 Chapter 16 中討論過)，當只使用Internet Explorer時，可幫您降低圖像等待時間。Structured graphics在代替簡單的點距陣圖形例如圓形，方形，或橢圓等特別有用。

部分圖像所涵蓋的面積應該顯示

若您使用 GIF格式來製作您的圖檔，您可以將在圖像中的某種顏色變成透明，這表示在之後的任何元件將會穿透過透明顏色後顯示。程式 A-4展示兩個不同的圖檔在放在一個背景圖案之前。可以在body上執行。圖A-2顯示結果。10

<HTML>
<HEAD>
<TITLE>Listing A-4</TITLE>
</HEAD>
<BODY BACKGROUND="back.gif">
<IMG SRC="dhtml.gif" WIDTH=108 HEIGHT=26 ALT="" BORDER="0">
<IMG SRC="dhtmltrans.gif" WIDTH=108 HEIGHT=26 ALT="" BORDER="0">
</BODY>
</HTML>
程式A-4

圖A-2　第二圖像在字母周圍使用透明的區域

就像您所在 圖2-2所看到的，第一個圖有完整區塊的背景。第二個圖讓字母周圍的背景變透明且可以穿透。當我們建立第二個圖像時，我們只要指定白色且視為透明，結果如圖所示，通常這都是利用圖像編輯器來完成並儲存成檔案的。

窗格與表格使用上有問題

窗格和表格似乎最容易讓許多人頭痛。一個常見的錯誤就是永不結束的窗格。網站設計者有時會在窗格中提供一些無法連到窗格外的連結，如此會導致一個情況就是相同的窗格會一直重複，或來自不同網站的窗格會混在一起。11

解決方式就是提供一個離開窗格的方法，即一個連結指向top視窗。舉例來說，若一個連結指向www.w3.org，及會在目前的窗格直接開啟網頁，但是加入TARGET= "_top" 到anchor標籤會在top視窗中開啟網頁，而取代網頁中的所有窗格。

另一個常見的問題就是不適當的巢狀窗格 (nested)。對於窗格來說，FRAME元件應該要放在一個FRAMESET元件之內，就有如下面原始碼所示:

<FRAMESET COLS="25%,*" FRAMESPACING=0 FRAMEBORDER="yes">
      <FRAME NAME="frame1" SRC="frame1.htm" FRAMESPACING=0>
      <FRAMESET ROWS="15%,*" FRAMESPACING=0 FRAMEBORDER="yes">
        <FRAME NAME="frame2" SRC="frame2.htm" FRAMESPACING=0>
        <FRAME NAME="frame3" SRC="frame3.htm" FRAMESPACING=0>
      </FRAMESET>
    </FRAMESET>

在表格中，儲存格 ( TD元件) 必須要放在適當的元件之內，例如TR，THEAD，或TFOOT，它們必須按照順序放入TABLE元件之內。若您的窗格或表格沒有正確顯示，請檢查看看所有元件是否放置在正確的巢狀位置。記得您可以使用邊框 (borders) 來測試窗格和表格，即使您並不會在最後的版本中放入邊框。當您建立網頁時使用邊框，可有助於觀察邊框或表格如何顯示且當問題發生時有助於您除錯。

網頁永遠都有捲動軸，既使不需要

一個標準的Internet Explorer視窗都有捲動軸，不過您並不永遠需要它 (舉例來說，當網頁中沒有文字時)。一般來說，在Netscape Navigator中，這並不是問題。您可以透過設定BODY中的SCROLL屬性為no，就可以移除捲動軸。然而，使用這種方法時要小心，因為它會完全移除捲動軸，這表示使用者可能無法存取一些網頁，若它們的視窗在較低的解析度，或如果它們使用和您不同的字體。

這裡有些方法可使捲動軸當需要時才自動出現。若您在網頁使用窗格，您可以設定FRAME元件的SCROLLING屬性為auto，則只有當網頁超過窗格邊界外時捲動軸會自動出現。在單一網頁，您可以將整個網頁放到一個大的DIV元件中，然後設定長度與寬度為視窗百分之100 ，然後將overflow CSS屬性設定為auto。若您使用這個方法，您將會想要設定BODY的TOPMARGIN和LEFTMARGIN屬性為0且它的SCROLL屬性為no，如此來確保DIV元件會延伸到視窗的邊界。下面的原始碼片段展示如何使用第二個方法：12

<BODY SCROLL="no" LEFTMARGIN="0" TOPMARGIN="0">
  <DIV STYLE="overflow:auto;width:100%;height:100%"> [The document content goes here] <DIV>
  </BODY>
實戰Dynamic HTML網站技術 視窗縮放
Appendix A 解決一些疑難雜症


實戰Dynamic HTML網站技術=>Appendix B 好用的工具和資源

Appendix B 好用的工具和資源
小
工
具 加入書架
加入書籤
上一章
下一章

本附錄列出許多我們發現好用的工具與資源。它沒辦法涵蓋所有可在Web上使用的工具，不過它應該可以引導您開始使用一些其他有用的資訊。

這裡所列出的工具大都是shareware或 freeware，且可以在 Internet上許多不同網站上下載。一些我們最喜愛的下載網站，如下所示：

  • http://www.hotfiles.com/
  • www.tucows.com1
  • http://www.windows95.com/
  • http://www.download.com/
  • oak.oakland.edu
  • http://www.davecentral.com/

HTML/Script編輯器

Notepad 這是內建於Microsoft Windows中功能有限的文字編輯器。有時被戲稱為 "Visual N++"。

Allaire HomeSite 軟體網站為2 http://www.allaire.com/ 。這個十分有彈性的文字編輯器是我們喜歡使用的編輯器之一。它包含了許多有用的設計網頁功能，例如說將原始碼以顏色區分，強大的多重檔案搜尋與替代，自動完成標籤名稱，HTML規格驗證，與Microsoft Internet Explorer整合，網站與專案管理工具，一個選用的WYSIWYG觀看程式，和自動調整插入圖像的寬度與高度。

Microsoft FrontPage 軟體網站為 microsoft.com/frontpage 。這套網站工具包括了一個WYSIWYG編輯器，此編輯器能輸出比任何一個WYSIWYG編輯器，更高品質的HTML檔案。不像許多WYSIWYG編輯器，Frontpage 2000並不會修改開發者自行鍵入的HTML文件。

Microsoft FrontPage Express 軟體網站 microsoft.com/ie3 。這個WYSIWYG編輯器是Internet Explorer完整安裝的一部份。FrontPage Express使用上有些限制，不過它是免費且容易使用。

Microsoft Visual InterDev 軟體網站為 msdn.microsoft.com/vinterdev 。這個 Visual Studio-based工具是一個完整的開發平台環境，能讓您透過ASP (Active Server Pages) 即可簡單地建立一個連結資料的互動網站。

Microsoft Script Debugger 軟體網站為 msdn.microsoft.com/scripting 。這是用來替Script除錯的有用工具且讓您可追蹤您的程式執行，及可設定breakpoints來偵測目前變數值。4

Adobe PageMill 軟體網站為 http://www.adobe.com/ 。這個WYSIWYG編輯工具包含一個 Adobe Photoshop image editor 的限定版本且附有很多圖片和動畫。

Sausage Software HotDog 軟體網站為 http://www.sausage.com/ 。這是一個受歡迎的HTML editor，它包括了許多不同的精靈，使建立文件更容易，也支援將程式碼以色彩區分，且支援協力廠商的plig-ins。

SoftQuad HoTMetaL PRO 軟體網站為5 http://www.softquad.com/ 。這個HTML editing tool提供三種編輯環境WYSIWYG，且HTML標籤與原始碼以顏色做區別。它也提供內建的HTML規格測試程式確保您的HTML原始碼是正確的。

Allaire Cold Fusion 軟體網站為 http://www.allaire.com/ 。這項工具讓您更容易去建立網站資料庫。

NetObjects Fusion 軟體網站為 www.netobjects.com6 。這個網站的管理與設計工具允許您管理整個網站，幫您管理個人網頁到設定整個網站的樣式。

Macromedia Dreamweaver 軟體網站為 http://www.macromedia.com/ 。這是第一個可設計出 Dynamic HTML網頁的WYSIWYG編輯環境。

Microsoft Office 97 軟體網站為 www.microsoft.com/office 。Microsoft Office支援輸出HTML格式且可以處理許多網頁所需要的功能。7

圖像編輯器

Adobe Photoshop 軟體網站為 http://www.adobe.com/ 。這是所有圖像編輯器的祖父級的軟體，且它已經在圖形設計工業中漸漸變成一個標準。

Microsoft PhotoDraw 2000 是針對編輯商業繪圖需要而設計的，這個新產品使用容易且包括超過20,000個圖像和一些剪圖。

Macromedia Fireworks 一個針對Web所設計的圖像程式，Fireworks讓您在輸出成最後圖像之前，使用向量格式來處理圖像。

Jasc Software Paint Shop Pro 軟體網站為8 http://www.jasc.com/ 。這個shareware程式是非常有用且相比較來說並不貴。它包含許多額外的工具，例如內建的視窗畫面擷取程式，和批次轉換工具，此外當然也有一個圖像瀏覽器。

The GIMP 軟體網站為 http://www.gimp.org/ 。GNU的圖像處理程式 (GNU Image Manipulation Program ; GIMP ) 是個功能強大，針對UNIX且免費散佈的圖像編輯器。它包含一個scripting介面和許多其他的進階特性，例如多重undo/redo。有些計劃將這個程式放到Windows平台上。

Equilibrium DeBabelizer 軟體網站為 www.equilibrium.com9 。這個工具對於批次處理圖像很有用。

Alchemy Mindworks Graphic 軟體網站為 http://www.mindworkshop.com/ 。此不昂貴的圖 Workshop 像工具包含了一個圖像瀏覽器和一個批次編輯器。

Microsoft FrontPage 軟體網站為 www.microsoft.com/frontpage 。這個產品包括一個圖像編輯器，一個動畫GIF編輯器，和一些不同其它的圖像工具，例如一個圖像地圖編輯器。10

GIF Animation工具

Microsoft GIF Animator 軟體網站為 microsoft.com/imagecomposer/gifanimator/gifanin.htm 。這個工具是Microsoft Image Composer ( FrontPage中的一個軟體) 的一部份，讓您利用一連串的GIF檔來建立一個動畫GIF，且它也可以將AVI電影轉換為動畫GIF檔。

Right to Left Software Animagic GIF 軟體網站為 rtlsoft.com 。這個工具會將動畫GIF檔最佳化。我們可使用它來將一個動畫GIF檔，壓縮成比它原來檔案大小的百分之2還小，且毫不失真。11

Alchemy Mindworks Gif Construction Set 軟體網站為 http://www.mindworkshop.com/ 。這個有彈性的GIF編輯工具讓您可以精確的操控GIF檔。它包含了不同的精靈，這些精靈有助於動畫的重組，且也讓您直接深入GIF檔的內容中來編輯。

視窗擷取工具

Microsoft Windows 一些最基本個視窗擷取工具都是跟隨Microsoft Windows出現的。只要簡單按Print Screen鍵即可複製全螢幕的畫面到剪貼簿中，然後您可以在圖像編輯器中將之貼上。若按下Alt-Print Screen組合鍵則只會擷取目前正在運作的視窗。

Microsoft HTML Help Image Editor 軟體網站為 microsoft.com/workshop/author/htmlhelp/download.asp12 。這個免費的擷取工具程式是我們的最愛。它讓擷取工作變得容易，不論是單獨視窗中的元件或是單一應用程式視窗或為全螢幕，它都能輕易擷取。它也包含了切割工具和色階轉換功能。

Hyperionics HyperSnap-DX 軟體網站為 http://www.hyperionics.com/ 。這個工具也是提供不同格式的視窗擷取功能。它能讓您擷取DirectX遊戲畫面，滑鼠指標，或整個視窗 (即使部分被捲在視窗外面)。

Pedagoguery Software Gif.gIf.giF 軟體網站為 www.cafe.net/peda/ggg 。這個工具擷取animatedGIFs在視窗中執行的動作。結果檔案十分小。13

Hyperionics HyperCam 軟體網站為 http://www.hyperionics.com/ 。此工具將執行在視窗中的動作建立成AVI動畫。

多媒體工具

Adobe Premiere 軟體網站為 http://www.adobe.com/ 。這個電影編輯器是一個工業標準。它的輸出支援所有標準數位影片格式，包含AVI和QuickTime. animated GIF plug-in也可從Adobe網站找到。14

Macromedia Shockwave, Flash and Director 軟體網站為 http://www.macromedia.com/ 。這些工具在Web上提供高品質，多媒體互動的功能，包含 streaming，向量為基礎且有聲光效果的動畫。

Sonic Foundry Sound Forge 軟體網站為 http://www.sonicfoundry.com/ 。此全功能的聲音編輯工具支援許多壓縮型態和檔案格式，包含WAV，AVI，和NetShow ASF。

可參考的資源15

Web上提供許多有用的資訊來源。書附光碟中的SBN Workshop網站就是一個最好的參考資料；而線上版本會定期更新資訊，您可在下列網址中找到： microsoft.com/workshop 。本書撰寫之時，此站的內容正準備要移動到the Microsoft Developer Network (MSDN) 網址為 msdn.microsoft.com 。它提供更多額外的資源 (當然，由於網站時常在更新，因此有可能有些站您會連不上)。

http://www.w3.org/ 領導Web標準的正式制定規格的網站。在此處您可以找到許多Web標準的完整規格書，例如：HTML，CSS，HTTP，XML，DOM，等等。16

microsoft.com/sitebuilder 此站包含文件，參考資料，和可下載的建立網站工具。 此站的內容計劃要轉移到msdn.microsoft.com，Microsoft Developer Network網站。

msdn.microsoft.com/scripting Microsoft的scripting參考資訊與教學文件網站。

developer.netscape.com/library/documentation/communicator/jsref/index.htm Netscape的JavaScript參考網站。這個站包括許多不錯的實例。

www.gamelan.com17 此站針對Java，JavaScript，ActiveX，和其他Internet技術提供資訊。

http://www.wdvl.com/ The Web Developer's Virtual Library。此站包含對於網站設計者有用的資訊，例如HTML，graphics，Java等等相關資訊的討論與介紹。

http://www.jars.com/ 此站包括了許多Web-based程式的source code列表。且包括許多how-to資訊。包含從電子商務( electronic commerce) 到HTML和 JavaScript的各種資訊。

http://www.webreview.com/ 此站包含了各種建立網站的資訊，從圖形設計到以技術觀點來維護一個大型網站。18

www.zdnet.com/devhead From Ziff Davis，一個電腦雜誌與書籍的出版公司的網站，此站包含許多參考資訊且也包含了一些業界名人所撰寫how-to資訊的文章。

msdn.microsoft.com Microsoft Developer Network。包含對於開發者最重要的參考資訊。

microsoft.com/data 提供最好的資料存取技術之網站，例如ADO。

JavaScript: The Definitive Guide 由David Flanagan撰寫且由O'Reilly & Associates出版，這是一本最好的JavaScript參考手冊。19

實戰Dynamic HTML網站技術 視窗縮放
Appendix B 好用的工具和資源


實戰Dynamic HTML網站技術=>Appendix C Dynamic HTML 物件模型之組成元件

Appendix C Dynamic HTML 物件模型之組成元件
小
工
具 加入書架
加入書籤
上一章
下一章

本附錄提供一個物件，屬性，事件，方法的完整列表，這個列表支援於Interner Explorer 5的Dynamic HTML物件模型，這邊所列的每個組成元件都可以在書附光碟的 SBN Workshop中找到詳細的說明；請參閱Workshop (References)；DHTML，HTML & CSS；DHTML References。

物件(Objects)

!DOCTYPE | H11 | PARAM
A | H2 | PLAINTEXT
ACRONYM | H3 | PRE2
ADDRESS | H4 | Q
APPLET | H5 | RB
AREA3 | H6 | RT
Attribute | HR | RUBY
B | HTML4 | runtimeStyle
BASE | HTMLAREA | rule
BASEFONT | I | S5
BDO | IFRAME | SAMP
BGSOUND | IMG | screen
BIG6 | INPUT | SCRIPT
BLOCKQUOTE | INPUT type=button | SELECT
BODY | INPUT type=checkbox7 | selection
BR | INPUT type=file | SMALL
BUTTON | INPUT type=hidden | SPAN8
CAPTION | INPUT type=image | STRIKE
CENTER | INPUT type=password | STRONG
CITE9 | INPUT type=radio | style
CODE | INPUT type=reset | STYLE
COL | INPUT type=submit10 | styleSheet
COLGROUP | INPUT type=text | SUB
COMMENT | INS | SUP11
currentStyle | ISINDEX | TABLE
dataTransfer | KBD | TBODY
DD12 | LABEL | TD
DEL | LEGEND | TEXTAREA
DFN | LI13 | TextNode
DIR | LINK | TextRange
DIV | LISTING | TextRectangle14
DL | location | TFOOT
document | MAP | TH
DT15 | MARQUEE | THEAD
EM | MENU | TITLE
EMBED | META16 | TR
event | navigator | TT
external | NEXTID | U17
FIELDSET | NOBR | UL
FONT | NOSCRIPT | userProfile
FORM18 | NOFRAMES | VAR
FRAME | OBJECT | WBR
FRAMESET | OL19 | window
HEAD | OPTION | XML
history | P | XMP20

屬性(Properties)

!important | disabled | parentNode
@charset | display | parentStyleSheet21
@font-face | documentElement | parentTextEdit
@import | domain | parentWindow
accessKey22 | dropEffect | pathname
action | dynsrc | pixelBottom
activeElement | effectAllowed23 | pixelHeight
align | encoding | pixelLeft
aLink | event | pixelRight24
aLinkColor | expando | pixelTop
alt face | pixel | Width
altHTML25 | fgColor | platform
altKey | fileCreatedDate | pluginspage
appCodeName | fileModifiedDate26 | port
appMinorVersion | fileSize | posBottom
appName | fileUpdatedDate | posHeight27
appVersion | filter | position
autocomplete | firstChild | posLeft
availHeight28 | font | posRight
availWidth | fontFamily | posTop
background | fontSize29 | posWidth
backgroundAttachment | fontSmoothingEnabled | previousSibling
backgroundColor | fontStyle | propertyName30
backgroundImage | fontVariant | protocol
backgroundPosition | fontWeight | readOnly
backgroundPositionX31 | form | readyState
backgroundPositionY | frame | reason
backgroundRepeat | frameBorder32 | recordNumber
balance | frameSpacing | recordset
behavior | fromElement | referrer33
bgColor | hash | rel
bgProperties | height | repeat
border34 | hidden | returnValue
borderBottom | host | rev
borderBottomColor | hostname35 | right
borderBottomStyle | href | rightMargin
borderBottomWidth | hspace | rowIndex36
borderCollapse | htmlFor | rows
borderColor | htmlText | rowSpan
borderColorDark37 | httpEquiv | rubyAlign
borderColorLight | id | rubyOverhang
borderLeft | imeMode38 | rubyPosition
borderLeftColor | indeterminate | rules
borderLeftStyle | index | screenLeft39
borderLeftWidth | innerHTML | screenTop
borderRight | innerText | screenX
borderRightColor40 | isMap | screenY
borderRightStyle | isTextEdit | scroll
borderRightWidth | keyCode41 | scrollAmount
borderStyle | lang | scrollDelay
borderTop | language | scrollHeight42
borderTopColor | lastChild | scrolling
borderTopStyle | lastModified | scrollLeft
borderTopWidth43 | layoutGrid | scrollTop
borderWidth | layoutGridChar | scrollWidth
bottom | layoutGridCharSpacing44 | search
bottomMargin | layoutGridLine | sectionRowIndex
boundingHeight | layoutGridMode | selected45
boundingLeft | layoutGridType | selectedIndex
boundingTop | left | selectorText
boundingWidth46 | leftMargin | self
browserLanguage | length | shape
bufferDepth | letterSpacing47 | shiftKey
button | lineBreak | size
cancelBubble | lineHeight | sourceIndex48
caption | link | span
cellIndex | linkColor | specified
cellPadding49 | listStyle | src
cellSpacing | listStyleImage | srcElement
charset | listStylePosition50 | srcFilter
checked | listStyleType | srcUrn
classid | loop | start51
className | lowsrc | status
clear | map | style
clientHeight52 | margin | styleFloat
clientInformation | marginBottom | systemLanguage
clientLeft | marginHeight53 | tabIndex
clientTop | marginLeft | tableLayout
clientWidth | marginRight | tagName54
clientX | marginTop | target
clientY | marginWidth | text
clip55 | maxLength | textAlign
clipBottom | media | textDecoration
clipLeft | menuArguments56 | textDecorationBlink
clipRight | method | textDecorationLineThrough
clipTop | Methods | textDecorationNone57
closed | multiple | textDecorationOverline
code | name | textDecorationUnderline
codeBase58 | nextSibling | textIndent
codeType | nodeName | textJustify
color | nodeType59 | textTransform
colorDepth | nodeValue | tFoot
cols | noHref | tHead60
colSpan | noResize | title
compact | noShade | toElement
complete61 | noWrap | top
content | object | topMargin
cookie | offscreenBuffering62 | trueSpeed
cookieEnabled | offsetHeight | type
coords | offsetLeft | uniqueID63
cpuClass | offsetParent | units
cssText | offsetTop | updateInterval
ctrlKey64 | offsetWidth | url
cursor | offsetX | urn
data | offsetY65 | useMap
dataFld | onLine | userAgent
dataFormatAs | opener | userLanguage66
dataPageSize | outerHTML | vAlign
dataSrc | outerText | value
defaultCharset67 | overflow | vcard_name
defaultChecked | overflowX | verticalAlign
defaultSelected | overflowY68 | visibility
defaultStatus | owningElement | vLink
defaultValue | padding | vlinkColor69
defer | paddingBottom | volume
designMode | paddingLeft | vspace
dialogArguments70 | paddingRight | width
dialogHeight | paddingTop | wordBreak
dialogLeft | pageBreakAfter71 | wordSpacing
dialogTop | pageBreakBefore | wrap
dialogWidth | palette | x72
dir | parent | y
direction | parentElement | zIndex

事件 (Events)73

onabort | ondblclick | onmousemove
onafterprint | ondrag | onmouseout
onafterupdate74 | ondragend | onmouseover
onbeforecopy | ondragenter | onmouseup
onbeforecut | ondragleave75 | onpaste
onbeforepaste | ondragover | onpropertychange
onbeforeprint | ondragstart | onreadystatechange76
onbeforeunload | ondrop | onreset
onbeforeupdate | onerror | onresize
onblur77 | onerrorupdate | onrowenter
onbounce | onfilterchange | onrowexit
oncellchange | onfinish78 | onrowsdelete
onchange | onfocus | onrowsinserted
onclick | onhelp | onscroll79
oncontextmenu | onkeydown | onselect
oncopy | onkeypress | onselectstart
oncut80 | onkeyup | onstart
ondataavailable | onload | onsubmit
ondatasetchanged | onlosecapture81 | onunload
ondatasetcomplete | onmousedown |

方法 (Methods)

add | empty82 | queryCommandIndeterm
addBehavior | execCommand | queryCommandState
AddChannel | execScript | queryCommandSupported83
AddDesktopComponent | execScript | queryCommandValue
AddFavorite | expand | recalc
addImport84 | findText | refresh
addReadRequest | firstPage | releaseCapture
addRule | focus85 | reload
alert | forward | remove
appendChild | getAdjacentText | removeAttribute86
applyElement | getAttribute | removeBehavior
assign | getBookmark | removeChild
attachEvent87 | getBoundingClientRect | removeExpression
back | getClientRects | removeNode
blur | getData88 | removeRule
clear | getExpression | replaceAdjacentText
clearData | go | replaceChild89
clearInterval | hasChildNodes | replaceNode
clearRequest | ImportExportFavorites | reset
clearTimeout90 | inRange | resizeBy
click | insertAdjacentElement | replace
cloneNode | insertAdjacentHTML91 | resizeTo
close | insertAdjacentText | scroll
collapse | insertBefore | scrollBy92
compareEndPoints | insertRow | scrollIntoView
componentFromPoint | isEqual | scrollTo
confirm93 | IsSubscribed | select
contains | item | setAttribute
createCaption | javaEnabled94 | setCapture
createControlRange | lastPage | setData
createDocumentFragment | move | setEndPoint95
createElement | moveBy | setExpression
createRange | moveEnd | setInterval
createStyleSheet96 | moveStart | setTimeout
createTextNode | moveToBookmark | showHelp
createTextRange | moveTo97 | showModalDialog
createTFoot | moveToElementText | showModelessDialog
createTHead | moveToPoint | splitText98
deleteCaption | navigate | swapNode
deleteCell | NavigateAndFind | tags
deleteRow99 | nextPage | taintEnabled
deleteTFoot | open | urns
deleteTHead | parentElement100 | write
detachEvent | pasteHTML | start
doReadRequest | previousPage | stop101
doScroll | print | submit
duplicate | prompt | writeln
elementFromPoint102 | queryCommandEnabled |

集合 (Collections)

all | behaviorUrns | children
anchors103 | bookmarks | controlRange
applets | boundElements | elements
areas | cells104 | embeds
attributes | childNodes | filters
forms | mimeTypes | scripts105
frames | options | styleSheets
images | plugins | tBodies
imports106 | rows | TextRectangle
links | rules |
實戰Dynamic HTML網站技術 視窗縮放
Appendix C Dynamic HTML 物件模型之組成元件


實戰Dynamic HTML網站技術=>Appendix D 前256個字元代碼

Appendix D 前256個字元代碼
小
工
具 加入書架
加入書籤
上一章
下一章

下面為前256個字元代碼的列表。許多一般使用在拉丁語系語言的字元和符號都可以在此列表中找。在書附光碟中AppndxD\appd.htm的範例檔案展示了所有這些字元代碼。更完整的字元代碼列表可以在書附光碟中SBN Workshop找到，請參考Workshop(References)；DHTML，HTML，& CSS；HTML References；Character Sets。要注意的是在不同作業系統中一些字元可能會以不同的字體來顯示。

Note

從 ；到 Ÿ的代碼是內定為 "保留" 的字元且沒有定義。然而，Netscape Navigator和Microsoft Internet Explorer都是如下列表一樣顯示的。

246810121416
顯示符號 | 數字關鍵字1 | 字元代碼 | 說明
 | &#00; |  | ot Used
 |  |  | Not Used
 |  |  | Not Used3
 |  |  | Not Used
 |  |  | Not Used
 |  |  | Not Used
 | 5 |  | Not Used
 |  |  | Not Used
 |  |  | Not Used
 |  |  | Horizontal tab7
 |  |  | Line feed
 |  |  | Not Used
 |  |  | Not Used
 | 9 |  | Carriage Return
 |  |  | Not Used
 |  |  | Not Used
 |  |  | Not Used11
 |  |  | Not Used
 |  |  | Not Used
 |  |  | Not Used
 | 13 |  | Not Used
 |  |  | Not Used
 |  |  | Not Used
 |  |  | Not Used15
 |  |  | Not Used
 |  |  | Not Used