跳至內容

XML - 資料交換管理/XUL

來自華夏公益教科書



上一章 下一章
解析 XML 檔案 AJAX



學習目標
  • 簡要了解 XUL 是什麼。
  • 瞭解基本標籤/小部件庫。
  • 建立一些簡單的靜態 XUL 網頁。
  • 向 XUL 頁面新增事件處理程式。

簡介

[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]

本章中顯示的示例只是觸及了 XUL 功能的表面。儘管這些示例非常簡單,但可以看出使用 XUL 建立更復雜的 UI 是多麼容易。使用一組完整的標準組件(如按鈕和文字框),程式設計師可以使用 XUL 編寫任何可以使用 HTML 編寫的程式碼。XUL 的跨平臺功能是另一個優勢,但它無法與微軟的 Internet Explorer 協同工作的事實可能會抑制 XUL 的廣泛使用。有一點希望,由於下一版 IE 的開發延期,XUL 可能會進入 IE,但不要抱太大希望。

參考文獻

[edit | edit source]
  1. 'Configurable Chrome' by Dave Hyatt (hyatt@netscape.com) (Last Modified 4/7/99)
  2. XML User Interface Language (XUL) - The Mozilla Organization
  3. XulPlanet
  4. XUL 程式設計師參考手冊,第五版:更新至 XUL 1.0
華夏公益教科書