本帖最后由 hechengjin 于 2015-8-1 23:02 编辑
XUL布局要点探讨
1. 前言 此文档不是入门文档,我们将跳过XUL元素的基本特性及其属性、方法,将侧重点将放在发挥XUL的高级特性,搭建复杂布局的UI上。因此,我假定大家已经基本掌握了XUL的用法,并熟悉了一些基本元素及其属性。
2. 布局 与HTML网页不同,XUL引入了布局器,方便了UI元素的自适应,这更符合客户端布局的思维。XUL几乎不会用到绝对定位,任何复杂的布局都可以用各种布局器搭配和嵌套实现。
2.1 横向布局器hbox 顾名思义,就是将子元素横向排列的容器。hbox和下面要讲到的vbox,是最常用的布局器。
2.1.1 align属性 ---垂直排放方式 align属性指定了其子元素排列的对齐和拉伸细节,可选值如下:
2.1.2 元素的拉伸 每个XUL的UI元素都有一个flex属性,指定了元素的拉伸策略。为0时,表示元素不拉伸;为正整数(1,2,……)时,表示一个拉伸比例,和其他带有flex属性的兄弟元素分配宽度或高度。若元素在hbox里,表示横向拉伸;在vbox里,表示纵向拉伸。
2.1.3 弹簧片spacer spacer可视作一个不可见,但占据空间的元素,可拉伸,也可固定长/宽。与spacer元素配合,能实现更多的布局效果。
2.1.4 pack属性---水平排放方式 pack指定了hbox子元素的水平排放方式,可选值如下:
2.2 纵向布局器vbox vbox在功能和用法上和hbox完全一致,仅仅是子控件排列方式从横向变为了纵向。需要注意的是,vbox的align和pack排向方向相对于hbox也会有所变化。
2.3 表格布局器grid grid类似HTML中的table,是按行列式摆放元素的一种布局。一个典型的grid如下: <grid> <columns> <columnwidth="80"/> <columnflex="1"/> <columnwidth="100"/> </columns> <rows> <row> <labelvalue="row1"/> <textbox/> <button/> </row> <row> <labelvalue="row2"/> <menulist/> <button/> </row> </rows> </grid> 首先定义行数,然后逐行插入元素。row标签下的子元素数目应在grid的行数相同,如果超出则会造成grid布局的混乱。
2.4 栈式容器deck 有时我们要把多个元素放在同一个位置,每次只显示其中一个元素。其中一种方法是:把这些元素放在一个hbox或vbox里,每次控制一个元素显示,其他元素的hidden设置为true。这种方法很不灵活,假如元素组有变化,则js代码改动较大,其实我们可以用deck来实现。 <deck id="deck" selectedIndex=”2”> <hboxalign="center"> <labelvalue="page1"/> <textboxflex="1"/> </hbox>
<hboxalign="center"> <labelvalue="page2"/> <buttonlabel="button"/> </hbox>
<hboxalign="center"> <label value="page3"/> <textboxmultiline="true" flex="1" height="80"/> </hbox> </deck> 在这个示例中,deck中放入了3个子元素,控制deck的selectedIndex属性值,可以控制指定子元素的显示。
2.5 重叠式容器stack 之前介绍了几种典型的布局器,在这些布局器,元素的排列不是横向就是纵向的,一般不会发生重叠(其实修改margin也可以做到),但stack很特殊,可以让子元素重叠显示。先看个例子, <stack> <label value="Shadowed" style="padding-left: 3px;padding-top: 3px; font-size: 36px;"/> <label value="Shadowed"style="color: red; font-size: 36px;"/> </stack> 在这个stack窗口中,两个label元素发生重叠,产生了阴影效果。 stack并不常用,有些布局场景使用hbox、vbox等难以实现,就可以考虑引入stack,如日历中日视图中的当前时间线。
3. XBL XBL全称是eXtensibleBindings Language,在XUL中使用非常普遍。简单来说,可将它看成一种元素的封装,不但是布局、样式的封装,也是方法、事件的封装。有了它,我们可以创建XUL元素标签,像menulist、textbox一样来使用。 这个封装定义在一个xml文件里,一个xml里有一个bindings标签,bindings标签中可以有多个binding,一个binding对应一套绑定。 接下来我们做一个简单的实例recorder,来了解XBL的基本用法。这个recorder模型很简单,有一个输入框,一个记录按钮和一个清空按钮,一个记录集合列表。点击记录按钮,输入框中的内容将被追加到列表中,同时我们还可以使用XBL的方法来设置和获取列表中的数据。
3.1 元素绑定 我们可以为这套记录器创建一个新的元素标签:recorder,那么我们可以在CSS中为所有recorder元素绑定上这个XBL: recorder { -moz-binding: url(chrome://messenger/content/xulExample/recorder.xml#recorder); } 这表示,将recorder.xml下的recorder这一个binding绑定在recorder元素上。
3.2 引入样式 一个xul文件可以添加xml-stylesheet代码片段来引入css样式,而XBL是一个相对封闭空间,引入样式的方法为: <resources> <stylesheet src="chrome://messenger/content/xulExample/recorder.css"/> </resources>
3.3 元素封装 一个XBL元素可以视作一系列元素的集合,这些元素放在content标签下面,封装成一个整体。content标签即对应着绑定的元素,同样可以添加align、style等属性。
3.4 属性(attribute)继承 由于XBL元素是一个整体,其封装的元素的元素都变成了匿名元素,不直接暴露给外部DOM结构。而XBL引入了属性(attribute)继承,允许XBL元素的属性直接反应到内部元素,方法是给内部元素指定xbl:inherits属性来做映射。
3.5 定义属性(property)、方法 属性(property)和方法(method)是暴露给js用的,XBL中定义在implementation标签下。implementation可以有如下标签: field | 数据成员,一般是XBL内部使用,不暴露给js。但由于XBL和js对象的特性,外部js代码其实也可以访问这部分成员,这其实是XBL封装性比较差的地方。 | | XBL元素的构造方法。当一个元素在文档DOM中创建,或文档DOM中一个元素绑定完成一个XBL时,会执行这个方法。 | | XBL元素的析构方法。当一个元素在文档DOM中被移除,或文档DOM中一个元素的XBL解除绑定时,会执行这个方法。 | | 定义XBL元素的属性,暴露给外部js脚本中使用,可定义get和set读写方式,也可设置为只读。 | | |
3.6 事件处理 事件处理的代码放在handlers标签里,handlers可以有多个handler标签,一个handler对应一个事件处理模块。要注意的是,handler处理所有封装元素的事件,比如content里有多个textbox,则在每个textbox输入字符时,都会触发XBL元素的input事件。
xulExample.rar
(5.29 KB, 下载次数: 0)
|