XML - 資料交換管理/XUL
| 上一章 | 下一章 |
| ← 解析 XML 檔案 | AJAX → |
學習目標
|
簡介
[edit | edit source]XUL(發音為 zool,與 cool 押韻),代表可擴充套件使用者介面語言,是一種基於 XML 的使用者介面語言,最初是為在 Netscape 瀏覽器中使用而開發的。現在由 Mozilla 維護。它是 Mozilla Firefox 和許多其他 Mozilla 應用程式的一部分,並且作為 Gecko(Mozilla 開發的渲染引擎)的一部分提供。事實上,XUL 功能強大,以至於 Firefox 應用程式中的整個使用者介面都是用 XUL 實現的。
與 HTML 一樣,在 XUL 中,您可以使用相對簡單的標記語言建立介面,使用 CSS 樣式表定義外觀,並使用 JavaScript 來操作行為。但是,與 HTML 不同的是,XUL 提供了一組豐富的使用者介面小部件來建立例如選單、工具欄和選項卡面板。
簡單來說,XUL 可用於建立輕量級、跨平臺、跨裝置的使用者介面。
許多應用程式使用特定平臺的功能進行開發,這使得構建跨平臺軟體既耗時又昂貴。一些使用者可能希望在傳統計算機以外的技術上使用應用程式,例如小型手持裝置。迄今為止,已經開發出一些跨平臺解決方案。例如,Java 的建立正是為了這樣的目的。但是,使用 Java 建立 GUI 最好說是繁瑣的。或者,XUL 被設計用於輕鬆快速地構建可移植的使用者介面。它在大多數版本的 Windows、Mac OS X、Linux 和 Unix 上都可用。Yahoo!目前在其 Yahoo!工具欄(Firefox 擴充套件)和 Photomail 應用程式中使用 XUL 和相關技術。
為了說明 XUL 的潛力,本章將逐步介紹幾個示例。在這裡,潛力是恰如其分的詞語。XUL 的全部功能超出了本章的範圍,但它旨在讓讀者初識 XUL 的強大功能。還需要注意的一點是:您需要一個基於 Gecko 的瀏覽器(例如 Firefox 或 Mozilla Suite)或 XULRunner 才能使用 XUL。
基礎知識
[edit | edit source]XUL 是 XML,與所有優秀的 XML 檔案一樣,一個好的 XUL 檔案從標準 XML 版本宣告開始。目前,XUL 使用 XML 版本 1.0。
為了使您的 XUL 頁面看起來不錯,您必須在其中包含一個全域性樣式表。預設樣式表的 URI 是href = "chrome://global/skin/"。雖然您可以載入任意數量的樣式表,但最好先載入全域性樣式表。請看圖 1。請注意對“chrome”的引用。“chrome 是應用程式視窗的一部分,位於視窗的內容區域之外。工具欄、選單欄、進度條和視窗標題欄都是通常屬於 chrome 的元素示例。”(1) Chrome 是用於命名 XUL 應用程式中所有元素的描述性術語。把它想象成汽車外部的鍍鉻裝飾。它會吸引你的眼球。XUL 檔案中的元素是你在瀏覽器視窗中看到的元素。
所有 XML 文件都必須包含名稱空間宣告。XUL 開發人員提供了一個名稱空間,它顯示了他們是如何想出 XUL 這個名字的。(對於不知情的人來說,參考來自電影“捉鬼敢死隊”)
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
id="window identifier"
title="XUL page"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
. . . (add elements here)
</window>
接下來需要注意的是標籤<window>。這個標籤類似於 HTML 中的<body>標籤。所有元素都將存在於 window 標籤內。在圖 1 中,window 標籤具有三個非常重要的屬性。“id”屬性很重要,因為它是標識視窗的方式,以便指令碼可以引用它。雖然 title 屬性不是必需的,但最好提供一個描述性名稱。title 的值將顯示在視窗的標題欄中。下一個屬性非常重要。這告訴瀏覽器以什麼方向佈局 XUL 檔案中描述的元素。Horizontal 表示橫向。按順序排列在視窗中。Vertical 則相反;它以列格式新增元素。Vertical 是預設值,因此如果您沒有宣告此屬性,您將獲得垂直方向。
如前所述,XUL 文件用於建立使用者介面。UI 通常充滿了互動式元件,例如文字框、按鈕等。XUL 文件透過使用小部件來實現這一點,小部件是具有預定義行為的自包含元件。例如,按鈕將響應滑鼠點選,而選單欄可以容納按鈕。GUI 元件的所有正常接受的操作都內置於小部件中。已經存在一個豐富的小部件預定義庫,但由於它是開源的,任何人都可以為自己定義小部件或一組小部件。
小部件是“斷開的”,直到它們被程式設計為一起工作。這可以透過簡單的 JavaScript 或使用 C++ 或 Java 等更復雜的應用程式來完成。在本章中,我們將使用 JavaScript 來說明 XUL 的用途和潛力。
此外,XUL 檔案應具有 .xul 副檔名。Mozilla 瀏覽器將自動識別它,並在您點選它時知道該如何處理它。或者,可以使用 .xml 副檔名,但您必須在瀏覽器中開啟該檔案。
還需要提一下,有一些語法規則需要遵循,它們是
- 所有事件和屬性都必須用小寫字母編寫。
- 所有字串都必須用雙引號括起來。
- 每個 XUL 小部件都必須使用結束標籤(<tag></tag> 或 <tag/>)以形成良好的格式。
- 所有屬性都必須有值。
第一個示例
[edit | edit source]還有什麼比使用久經考驗的“Hello World”示例更好的開始方式呢?開啟一個文字編輯器(不是 MS Word),比如記事本或 TextPad,然後輸入
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
id="Hello"
title="Hello World Example"
orient="vertical"
persist="screenX screenY width height"
xmlns= "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<description style='font-size:24pt'>Hello World</description>
<description value='Hello World' style='font-size:24pt'/>
<label value = 'Hello World' style='font-size:24pt'/>
</window>
將其儲存到任何地方,但確保將副檔名設定為 .xul。現在只需雙擊它,它應該在您的 Mozilla 或 Netscape 瀏覽器中開啟。您應該看到“Hello World”三次,一次疊一次。請注意“Hello World”列印的不同方式:兩次來自 description 標籤,一次來自 label 標籤。<description> 和 <label> 都是與文字相關的標籤。使用 description 標籤是唯一一種可以編寫不是“value”屬性內容的文字的方式。這意味著您可以編寫不一定會分配給變數的文字。在第二個和第三個示例中,文字分別作為 description 或 label 標籤的屬性表達。您可以在這裡看到 window 中的 orient 屬性設定為“vertical”。這就是文字以列形式輸出的原因。否則,如果 orient 設定為“horizontal”,所有文字都將在一行上。試試看。
現在讓我們開始新增一些更有趣的元素。
新增小部件
[edit | edit source]如前所述,XUL 擁有一個現有的豐富的小部件庫,這些小部件被稱為小部件。它們包括按鈕、文字框、進度條、滑塊以及許多其他有用的專案。一個很好的清單是 XUL 程式設計師參考.
讓我們看看一些簡單的按鈕。輸入以下程式碼並將其放置到一個不是 MS Word 的記事本或其他文字編輯器中。
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<button id="find-button" label="Find" default="true"/>
<button id="cancel-button" label="Cancel"/>
</window>
將其儲存並將其副檔名設定為 .xul。開啟 Mozilla 或 Netscape 瀏覽器並從瀏覽器中開啟該檔案。您應該看到一個“查詢”按鈕和一個“取消”按鈕。從這裡可以新增更多功能並構建出精美的介面。
必須有一個地方放置所有這些東西,與 HTML 中的<body>標籤類似,XUL 中的<box>標籤用於容納小部件。換句話說,框是封裝其他元素的容器。<box> 有許多不同的型別。在本例中,我們將使用<hbox>、<vbox>、<toolbox> 和 <tabbox>。
<hbox> 和 <vbox> 等同於屬性“orient = "horizontal"”和“orient = "vertical"”,它們分別構成<window>標籤。透過使用這兩個框,視窗的離散部分可以擁有自己的方向。這兩個元素可以容納所有其他元素,甚至可以巢狀。
標籤<toolbox> 和 <tabbox> 用於特殊目的。<toolbox> 用於在視窗頂部或底部建立工具欄,而<tabbox> 用於在視窗中設定一系列選項卡。
從圖 1 中獲取 XUL 框架,並用<vbox>標籤對(即開啟和關閉標籤)替換“...(在此處新增元素)”。這將成為其他元素的外部容器。請記住,<vbox> 表示元素將按出現的順序垂直排列。新增屬性“flex="1"”。這將使選單欄擴充套件到整個視窗。
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox flex="1">
(... add elements here)
</vbox>
</window>
“flex” 屬性需要一些解釋,因為它是在頁面上調整元素大小和定位的主要方式。Flex 是一種在視窗中動態調整小部件大小和定位的方式。flex 數字越大(1 為最大),小部件在大小和位置方面獲得的優先順序就越高,而 flex 設定較低的小部件則優先順序較低。所有元素都有尺寸屬性,如寬度和/或高度,可以設定為特定數量的畫素,但使用 flex 可以確保在調整視窗大小時保持相同的相對大小和位置。
現在將一對 <toolbox> 和 <tabbox> 標籤放在 <vbox> 標籤中,其中 <toolbox> 放在前面。如前所述,<toolbox> 用於建立工具欄,所以讓我們新增一個類似於瀏覽器頂部的工具欄。
到目前為止的程式碼如下
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox flex="1">
<toolbox>
<menubar id="MenuBar">
<menu id="File" label="File" accesskey="f">
<menupopup id="FileMenu">
<menuitem label="New" accesskey="n"/>
<menuitem label="Open..." accesskey="o"/>
<menuitem label="Save" accesskey="s"/>
<menuitem label="Save As..." accesskey="s"/>
<menuitem label=" ... "/>
<menuseparator/>
<menuitem label="Close" accesskey="c" />
</menupopup>
</menu>
<menu id="Edit" label="Edit" accesskey="e">
<menupopup id="EditMenu">
<menuitem label="Cut" accesskey="t" acceltext="Ctrl + X"/>
<menuitem label="Copy" accesskey="c" acceltext="Ctrl + C"/>
<menuitem label="Paste" accesskey="p" disabled="true"/>
</menupopup>
</menu>
<menu id="View" label="View" accesskey="v">
<menupopup id="ViewMenu">
<menuitem id="Tool Bar1" label="Tool Bar1"
type="checkbox" accesskey="1" checked="true"/>
<menuitem id="Tool Bar2" label="Tool Bar2"
type="checkbox" accesskey="2" checked="false"/>
</menupopup>
</menu>
</menubar>
</toolbox>
<tabbox>
</tabbox>
</vbox>
</window>
現在應該有一個選單欄,其中包含“檔案 編輯 檢視”,它們都應該在您單擊它們時展開。讓我們更仔細地檢查這些元素及其屬性,看看它們是如何工作的。
首先,<menubar> 包含所有選單項(檔案、編輯、檢視)。接下來是三個不同的選單項。每個選單都有一組元素和屬性。<menupopup> 顧名思義。它建立單擊選單標籤時出現的彈出選單。彈出選單中是選單項列表。每個選單項都有一個“accesskey” 屬性。此屬性將字母下劃線,並提供用於為該選單項建立熱鍵的參考。請注意,在“編輯”選單中,“剪下”和“複製”都有加速器文字標籤。在“檔案”選單中,有一個 <menuseperator/> 標籤。這會在選單中放置一條橫線,作為視覺分隔線。在“編輯”選單中,請注意標記為“貼上”的選單項有一個屬性:disabled="true"。這將導致“貼上”標籤在該選單中變灰,最後在“檢視”選單中,選單項實際上是複選框。第一個預設選中,第二個未選中。
現在繼續 <tabbox>。讓我們製作三個不同的工作表,並在上面放置不同的元素。將此程式碼放在 <tabbox> 標籤之間
<tabbox flex="1">
<tabs>
<tab id="Tab1" label="Sheet1" selected="true"/>
<tab id="Tab2" label="Sheet2"/>
<tab id="Tab3" label="Sheet3"/>
</tabs>
<tabpanels flex="1">
<tabpanel flex="1" id="Tab1Sheet" orient="vertical" >
<description style="color:teal;">
This doesn't do much.
Just shows some of the style attributes.
</description>
</tabpanel>
<tabpanel flex="1" id="Tab2Sheet" orient="vertical">
<description class="normal">
Hey, the slider works (for free).
</description>
<scrollbar/>
</tabpanel>
<tabpanel flex="1" id="Tab3Sheet" orient="vertical">
<hbox>
<text value="Progress Meter" id="txt" style="display:visible;"/>
<progressmeter id="prgmeter" mode="undetermined"
style="display:visible;" label="Progress Bar"/>
</hbox>
<description value="Wow, XUL! I mean cool!"/>
</tabpanel>
</tabpanels>
</tabbox>
標籤首先使用 <tab> 定義。它們被賦予了 ID 和標籤。接下來,建立了一組關聯的面板,每個面板都有不同的內容。第一個是用來展示如何像 HTML 樣式表一樣在行內應用樣式。後兩個工作表在其內容中包含元件型別元素。看看滑塊是如何工作的,進度條正在自行執行。
XUL 有多種型別的元素用於建立列表框。列表框以列表的形式顯示專案。可以選中此類特定列表中的任何專案。XUL 提供兩種型別的元素來建立列表,listbox 元素用於建立多行列表框,menulist 元素用於建立下拉列表框,正如我們已經看到的。
最簡單的列表框使用 listbox 元素表示框本身,listitem 元素表示每個專案。例如,此列表框將有四行,每行表示一個專案。
<listbox>
<listitem label="Butter Pecan"/>
<listitem label="Chocolate Chip"/>
<listitem label="Raspberry Ripple"/>
<listitem label="Squash Swirl"/>
</listbox>
與 HTML 的 option 元素一樣,可以使用 value 屬性分配值。列表框將設定為正常大小,但可以使用 row 屬性將大小更改到一定程度。將其設定為在列表框中顯示的行數。將自動出現一個捲軸,讓使用者能夠看到列表框中其餘的專案,如果框太小的話。
<listbox rows="3">
<listitem label="Butter Pecan" value="bpecan"/>
<listitem label="Chocolate Chip" value="chocchip"/>
<listitem label="Raspberry Ripple" value="raspripple"/>
<listitem label="Squash Swirl" value="squash"/>
</listbox>
將值分配給每個 listitem 使得使用者以後可以使用指令碼引用它們。這樣,其他元素可以參考此專案以用於其他目的。
所有這些元素都很好,也很容易放到視窗中,但它們本身什麼也做不了。現在,我們必須用一些其他程式碼將它們連線起來。
新增事件處理程式並響應事件
[edit | edit source]為了使事情真正有用,必須進行某種型別的指令碼或應用程式級編碼。在我們的示例中,將使用 JavaScript 為元件新增功能。這與使用 HTML 進行指令碼編寫的方式類似。使用 HTML,事件處理程式與元素相關聯,當該處理程式被啟用時,將啟動某個操作。在 XUL 中也找到了與 HTML 一起使用的大多數處理程式,除了某些獨特的處理程式。指令碼可以在額外的程式碼行中完成,但更有效的方式是建立一個包含所需指令碼的單獨檔案。這樣可以使頁面載入更快,因為渲染引擎不必決定如何處理嵌入的指令碼標籤。
話雖如此,我們將首先在行內新增一個簡單的指令碼,作為第一個示例。
讓我們新增一個“onclick” 事件處理程式,以便在選中元素時觸發一個警報框。在 <window> 標籤中新增以 onclick 開頭的行
<window
onclick="alert(event.target.tagName); return false;"
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
(... add elements here)
</window>
現在,當您單擊視窗中的任何元素時,您建立了一個警報框,彈出並告訴您元素的名稱。值得注意的是:當您單擊 description 標籤包含的文字時,響應為 undefined,但當您單擊 label 標籤包裝的文字時,您會得到 tabName 標籤。
這意味著 description 標籤並不是真正的元素。在玩完警報框後,刪除該行,並在“檔案”選單中“關閉”選單項的起始標籤內新增以下內容
oncommand="window.close()"
現在,當您單擊“關閉”或使用“C”作為熱鍵時,整個視窗將關閉。oncommand 事件處理程式實際上比 onclick 更受歡迎,因為 oncommand 可以處理熱鍵和其他非滑鼠事件。
讓我們再試一次。將此新增到起始 <window> 標籤的後面。
<script>
function show()
{
var meter=document.getElementById('prgmeter');
meter.setAttribute("style","display: visible;");
var tx=document.getElementById('txt');
tx.setAttribute("style","display: visible;");
}
function hide()
{
var meter=document.getElementById('prgmeter');
meter.setAttribute("style","display: none;");
var tx=document.getElementById('txt');
tx.setAttribute("style","display: none;");
}
</script>
這兩個函式首先使用它們的 id 獲取對進度計和文字元素的引用。然後,這兩個函式都將進度計和文字元素的樣式屬性設定為具有“visible”或“none”的顯示,這將恰好完成這些操作:隱藏或顯示這兩個元素。(必須顯示進度計的 tabpanel 才能看到這些操作)
現在新增兩個按鈕,它們將提供事件來觸發這兩個方法。首先,新增一個新的 box 元素來容納按鈕。必須設定 box 的 width 屬性,否則按鈕將被佈局為擴充套件視窗的長度。
<box width="200px">
<button id="show" label="Show" default="true" oncommand="show();"/>
<button id="hide" label="Hide" default="true" oncommand="hide();"/>
</box>
樣式表
[edit | edit source]樣式表可以用於建立主題,也可以用於修改元素以建立更精美的使用者介面。XUL 使用 CSS(層疊樣式表)來實現這一點。樣式表是一個檔案,它包含元素的樣式資訊。樣式表使得可以將特定字型、顏色、邊框和大小應用於您選擇的元素。Mozilla 將預設樣式表應用於每個 XUL 視窗。到目前為止,這就是已用於所有 XUL 文件的樣式表
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
該行賦予 XUL 文件預設的 chrome://global/skin/ 樣式表。在 Mozilla 中,這將被解釋為檔案 global.css,其中包含 XUL 元素的預設樣式資訊。如果省略了這一行,檔案仍然會顯示,但外觀不會那麼美觀。樣式表應用主題特定的字型、顏色和邊框,使元素看起來更適合。儘管樣式表可以提供更好看的檔案,但新增樣式並不總是能提供更好的檢視。一些 CSS 屬性不會影響小部件的外觀,例如那些更改大小或邊距的屬性。在 XUL 中,應該使用“flex: 屬性”而不是使用特定大小。還有其他 CSS 不適用的方法,對於本教程來說可能過於高階。
如果您已經制作了樣式表,您只需要插入一行額外的程式碼,指向您已經制作的 CSS 檔案。
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="findfile.css" type="text/css"?>
這第二行程式碼引用了樣式表,並將接管作為 XUL 文件使用的預設樣式表。有時,您可能不希望使用預設 CSS 檔案附帶的樣式。
答案
[edit | edit source]結論
[edit | edit source]本章中顯示的示例只是觸及了 XUL 功能的表面。儘管這些示例非常簡單,但可以看出使用 XUL 建立更復雜的 UI 是多麼容易。使用一組完整的標準組件(如按鈕和文字框),程式設計師可以使用 XUL 編寫任何可以使用 HTML 編寫的程式碼。XUL 的跨平臺功能是另一個優勢,但它無法與微軟的 Internet Explorer 協同工作的事實可能會抑制 XUL 的廣泛使用。有一點希望,由於下一版 IE 的開發延期,XUL 可能會進入 IE,但不要抱太大希望。
參考文獻
[edit | edit source]- 'Configurable Chrome' by Dave Hyatt (hyatt@netscape.com) (Last Modified 4/7/99)
- XML User Interface Language (XUL) - The Mozilla Organization
- XulPlanet
- XUL 程式設計師參考手冊,第五版:更新至 XUL 1.0