跳至内容

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 ([email protected]) (Last Modified 4/7/99)
  2. XML User Interface Language (XUL) - The Mozilla Organization
  3. XulPlanet
  4. XUL 程序员参考手册,第五版:更新至 XUL 1.0
华夏公益教科书