使用 Dojo 提供的灵活多样的布局方式

Dojo 提供了多种基本的布局方式,使用这些布局,可以有层次,有意义的组织控件,使得 web 界面获得更好的用户体验。本文从常见的几种控件出发,介绍 Dojo 常见的布局方式。

陈 悦, 软件工程师, IBM

陈悦,现就职于 IBM 中国开发中心,主要从事 Tivoli ITCAM 产品的原型开发工作。开源软件的追随者。



徐 文霞, 软件工程师, IBM

徐文霞现就职于 IBM 中国开发中心,从事软件研发工作。开源软件的追随者。



2010 年 8 月 05 日

前言

Dojo 提供了多种基本的布局方式,使用这些布局,可以有层次,有意义的组织控件,使得 web 界面获得更好的用户体验。

下面将从常见的几种控件出发,介绍 Dojo 常见的布局方式,让我们一起学习 Dojo 灵活而又丰富的布局方式。


基本布局方式

Dojo 基本布局方式主要体现在下列几种控件:

  • ContentPane (dijit.layout.ConentPane)
  • TitlePane (dijit.TitlePane)
  • FloatingPane (dojox.layout.FloatingPane)
  • ScrollPane(dojox.layout.ScrollPane)
  • BorderContainer (dijit.layout.BorderContainer)

ContentPane (dijit.layout.ConentPane)

ContentPane,顾名思义,就是用于放置若干内容的面板,是各种布局的基本元素。ContentPane 的功能类似于 iFrame。除此之外 ContentPane 还可以与其他 Layout 控件互相嵌套。首先看一个最简单的 ContentPane 的例子:

清单 1. ContentPane 声明法示例
 <head> 
 <link rel="stylesheet" type="text/css" href="ibmdojo/dijit/themes/soria/soria.css"> 
 <style type="text/css"> 
 body, html { font-family:helvetica,arial,sans-serif; font-size:90%; } 
 </style> 
 </head> 
 <script type="text/javascript" src="ibmdojo/dojo/dojo.js" djConfig="parseOnLoad:true"> 
 </script> 
 <script type="text/javascript"> 
 dojo.require("dijit.layout.ContentPane"); 
 </script> 
 <body class="soria"> 
        <div dojoType="dijit.layout.ContentPane" id="myFirstContentPane" 
 href="TestContentPane.html"> 
 </div> 
 </body>
清单 2. ContentPane 程序生成法示例
…
 <script type="text/javascript"> 
 dojo.require("dijit.layout.ContentPane"); 
 dojo.addOnLoad(function(){ 
 var myFirstContentPane = new dijit.layout.ContentPane({ 
 id: "myFirstContentPane", 
 href:"testcontentPane.html"
 },dojo.byId("myFirstContentPane")); 
 myFirstContentPane.startup(); 
 }); 
 </script> 
 <body class="soria"> 
 <div id="myFirstContentPane"> 
 </div> 
 </body>

在这个例子中,ContentPane 完全实现了 iFrame 的功能,当然,ContentPane 的功能不止这些。值得注意的是:1. 在使用声明法时,不要忘记 dojoType 属性,2. 在使用程序生成法时,不要忘记 startup(),3. 如果 href 页面中 require 的 dojo 控件,在调用页面中必须再 required 一次,否则子页面的 dojo 控件会解析 / 创建失败。

ContentPane 控件有一些经常会用到的属性和方法,下面予以一一介绍:

content – String, DomNode, NodeList

content 顾名思义,就是指 ContentPane 中显示的内容。如果没有定义 href 属性,ContentPane 组件内将显示 content 内容。否则将显示 href 页面的内容。content 可以是 String, DomNode 和 NodeList 三种类型。下面例子给出了 content 使用方法。

清单 3. ContentPane: content 属性示例 1
…
 var myFirstContentPane = new dijit.layout.ContentPane({ 
 id: "myFirstContentPane", 
 content: "Hello, Dojo World!"
 },dojo.byId("myFirstContentPane")); 
…

浏览器将显示如下信息:

图 1. content 属性示例 1
图 1. content 属性示例 1
清单 4. ContentPane: content 属性示例 2
…
 var myDomNode = document.createElement("table"); // 创建一个 DomNode, table 元素
 var myTD1 = document.createElement("td"); 
 myTD1.innerHTML = "Hello, Dojo World!"; 
 var myTR1 = document.createElement("tr"); 
 myTR1.appendChild(myTD1); 
 myDomNode.appendChild(myTR1); //Table 的第一行是”Hello, Dojo World!”

 var myTD2 = document.createElement("td"); 
 myTD2.innerHTML = "Hello, ContentPane World!"; 
 var myTR2 = document.createElement("tr"); 
 myTR2.appendChild(myTD2); 
 myDomNode.appendChild(myTR2); //Table 的第二行是”Hello, ContentPane World!”
 myDomNode.border = 1; 

 var myFirstContentPane = new dijit.layout.ContentPane({ 
 id: "myFirstContentPane", 
 //href:"TestContentPane.html"
 content: myDomNode // 将创建的 DomNode 赋给 content 属性
 },dojo.byId("myFirstContentPane")); 
…

浏览器将显示如下信息:

图 2. content 属性示例 2
图 2. content 属性示例 2

title – String

title 属性定义了 ContentPane 的标题。这个标题只有当 ContentPane 作为 TabContainer/ StackContainer 等 Layout 控件的子控件时,才可以看到。此时该属性值显示于该 Tab 页的标题处。下图展示了这一情形。

图 3. title 属性示例
图 3. title 属性示例

closable -- boolean

closable 属性同 title 属性一样,也是在作为 TabContainers 等 Layout 控件的子控件时,才有意义。如在 TabContainer 中,如果 closable=”true”,那么该 tab 页面的标题处会显示用于关闭 tab 的图标。下图展示了 closable = “true”时的情形:

图 4. closable 属性示例
图 4. closable 属性示例

点击小圆叉,first 页面将会被关闭:

图 5. closable 属性示例 2
图 5. closable 属性示例 2

loadingMessage / errorMessage -- String

当 ContentPane 内容 / 页面加载中,或出现错误时,ContentPane 将会显示的内容。

清单 5. ContentPane: loadingMessage 属性示例
…
 myContentPane.attr("loadingMessage", "Still Loading …"); 
…

placeAt() -- function

这是一个常用的方法,dojo 控件都实现了这个方法。运用这个方法可以自由地放置控件的位置。该方法有两个参数:reference, 和 position。可以接受的 reference 参数类型有:String, DomNode 和 _Widget。其中 String 为引用 Dom 节点 (DomNode),或者 dojo 控件 (_Widget) 的 id。而被座位参数传入的 dojo 控件,必须是实现了 addChild 方法的类型的。可接受的 position 参数类型有 Int, 和 String。传入的 String 参数必须是”first”,”last”,”before”,”after”中的一个。举一个例子:

清单 6. ContentPane: placeAt() 方法示例
…
 myContentPane.placeAt("OuterContentPane", "first"); 
…

该例子中,myContentPane 将被嵌套放入 OuterContentPane 的第一个位置。

attr() – function

attr 是常用的 dojo 控件通用方法。该方法在前面的例子已经出现过了,用于为 dojo 控件的属性赋值。如:_Widget.attr(“value”, 3) 相当于 _Widget.setValue(3)。在新的版本中,许多用于修改属性的方法被不推荐了,如 setValue, setHref 等,均由 attr(“value”, value), attr(“href”, href) 方法取代。

ContentPane 还支持 dojo 事件响应机制,用 connect 方法链接 dojo 控件,事件,与事件处理方法。ContentPane 中定义的很多事件需要与其他布局容器结合才能显示效果,如在 TabContainer 中,可以加上对 ContentPane 的 onClose, onShow, onHide 等事件响应。

在这里,先给出一个事件响应的例子:

清单 7. ContentPane: 事件响应示例
…
 dojo.connect(myContentPane, "onClick", function(event){alert(“Click me!”);}); 
…

TitlePane (dijit.TitlePane)

TitlePane 本质上仍然是一个 ContentPane, 不同点是,TitlePane 自带了 Title 的显示。在 TitlePane 中,title 属性定义了显示的标题。显示效果如图所示:

图 6. TitlePane 示例
图 6. TitlePane 示例
清单 8. TitlePane: 基本示例
…
 <script type="text/javascript"> 
 dojo.require("dijit.TitlePane"); 
 dojo.addOnLoad(function(){ 
 var myTp= dojo.byId("myTitlePane"); 
        var otherTP = new dijit.TitlePane({content:"Hello World!", 
 title:"test placeAt",closable:false}); 
 otherTP.placeAt("last","before"); 
 otherTP.startup(); 
 }); 
 </script> 
 <body class="soria"> 
 <div dojoType="dijit.TitlePane" id="myTitlePane" title="A Title Pane"> 
 Hello World! First Line. 
 <p id="last">Hello World! Last Line.</p> 
 </div> 
 </body>

该例中展示了构造 TitlePane 的程序法与声明法,以及 placeAt 的使用方法。可以看出,除了引用为 dijit.TitlePane 外,其他用法均与 ContentPane 相同。

下面介绍 TitlePane 的一些常用属性:

close -- boolean

TitlePane 的内容可以被收起。close 属性定义了 TitlePane 是否处于收起状态。

清单 9. TitlePane:close 属性示例
…
 myTP.attr("close", true); 
…

除了通过程序收起面板,TitlePane 还可以通过点击顶部的标题,打开和收起面板主体。如下图所示:

图 7. TitlePane: close 属性示例 1
图 7. TitlePane: close 属性示例 1
图 8. TitlePane: close 属性示例 2
图 8. TitlePane: close 属性示例 2

duration -- number

收起和打开 TitlePane,是一个动画过程,duration 定义了该动画持续的时间,单位是毫秒。

清单 10. TitlePane:duration 属性示例
…
 myTP.attr("duration", 1000); 
…

下图展示了定义 duration 后收起 TilePane 时展示的动画过程瞬间。

图 9. TitlePane: duration 属性示例
图 9. TitlePane: duration 属性示例

通过例子,可以发现 TitlePane 也可以和 ContentPane 一样相互嵌套。但 TitlePane 不适合被嵌套在 StackContainer 中,这样会显得不伦不类:

图 10. TitlePane: 在 StackContainer 中的
图 10. TitlePane: 在 StackContainer 中的

FloatingPane (dojox.layout.FloatingPane)

FloatingPane 是可以随意移动的 TitlePane。

清单 11. FloatingPane: 声明法示例
…
 <head> 
 <link rel="stylesheet" type="text/css" href="ibmdojo/dijit/themes/soria/soria.css"> 
 <link rel="stylesheet" type="text/css" 
             href="ibmdojo/dojox/layout/resources/FloatingPane.css"> 
 <link rel="stylesheet" type="text/css" 
             href="ibmdojo/dojox/layout/resources/ResizeHandle.css"> 
 </head> 
 <script type="text/javascript" src="ibmdojo/dojo/dojo.js"
 djConfig="parseOnLoad: true"> 
 </script> 
 
 <script type="text/javascript"> 
 dojo.require("dojox.layout.FloatingPane"); 
 </script> 
 <body class="soria"> 
 <div dojoType="dojox.layout.FloatingPane" id="myFloatingPane" 
                              title="Floating World" closable="true"
 resizable="true" dockable="true" 
              style="position:absolute;top:0;left:0;width:150px;height:150px;"> 
 The Content of the Floating World! 
 </div> 
 </body>
清单 12. FloatingPane: 程序生成法示例
…
 <head> 
 <link rel="stylesheet" type="text/css" href="ibmdojo/dijit/themes/soria/soria.css"> 
 <link rel="stylesheet" type="text/css" 
                  href="ibmdojo/dojox/layout/resources/FloatingPane.css"> 
 <link rel="stylesheet" type="text/css" 
                 href="ibmdojo/dojox/layout/resources/ResizeHandle.css"> 
 </head> 
 <script type="text/javascript" src="ibmdojo/dojo/dojo.js"
 djConfig="parseOnLoad: true"> 
 </script> 
 
 <script type="text/javascript"> 
 dojo.require("dojox.layout.FloatingPane"); 
 dojo.addOnLoad(function(){ 
 var myFP = new dojox.layout.FloatingPane({ 
 id: "myFloatingPane", 
 content: " The Content of the Floating World!", 
 resizable:true, 
 dockable:true, 
 title: "Floating World", 
 closable:true, 
 style:{ position:"absolute", top:0, left:0, width:"150px", height:"150px"} 
 },dojo.byId("myFloatingPane") 
 ); 
 myFP.startup(); 
 }); 
 </script> 
 <body class="soria"> 
 <div id="myFloatingPane" /> 
 </body>

需要注意的是:1. 必须引用 FloatingPane.css; 2. 如果需要具备改变容器大小 (resize) 功能,需引用 ResizeHandle.css.

上面创建方法得到的 FloatingPane 显示如下图所示,用户可以自由地在它的外层容器中移动位置:

图 11. FloatingPane: 移动 1
图 11. FloatingPane: 移动 1
图 12. FloatingPane 移动 2
图 12. FloatingPane 移动 2

下面介绍 FloatingPane 的一些常用属性:

closable -- boolean

与 TitlePane 相同,closable 属性定义了该面板是否可以被关闭。

resizable -- boolean

该属性定义了 FloatingPane 是否可以在运行时改变大小。当 resizable 为 true 并引用了 ResizeHandle.css 时,用户可以通过拖动控制点来改变面板的大小

图 13. FloatingPane: resizable 属性示例
图 13. FloatingPane: resizable 属性示例

dockable -- boolean

该属性定义了 FloatingPane 是否可以被最小化到页面的最下方。与 TitlePane 可以收起面板不同的是,FloatingPane 可以将面板最小化到页面的最下方,如同 Windows 的工具栏。当 dockable 为 true 时,用户可以通过点击面板标题位置向下的三角来最小化面板。最小化的结果如图所示:

图 14. FloatingPane: dockable 属性示例
图 14. FloatingPane: dockable 属性示例

sytle – object

该属性定义了面板的位置。其中 position 定义是绝对位置还是相对位置,top 和 left 定义了面板左上角的位置,width 和 height 定义了面板的大小。但当面板被拖动或改变大小时,该值不会跟着变化。


ScrollPane (dojox.layout.ScrollPane)

顾名思义,ScrollPane 是可以滚动的面板。当面板内容超出了面板显示范围时,使用 ScrollPane 可以让内容滚动起来。

清单 13. ScrollPane: 声明法示例
…
 <head> 
 <link rel="stylesheet" type="text/css" href="ibmdojo/dijit/themes/soria/soria.css"> 
       <link rel="stylesheet" type="text/css" 
 href="ibmdojo/dojox/layout/resources/ScrollPane.css"> 
 </head> 
 <script type="text/javascript" src="ibmdojo/dojo/dojo.js" djConfig="parseOnLoad: true"> 
 </script> 
 <script type="text/javascript"> 
 dojo.require("dijit.TitlePane"); 
 dojo.require("dojox.layout.ScrollPane"); 
 dojo.require("dojo.parser"); 
 </script> 
 <body class="soria"> 
 <div style="float:left; padding-right:12px;"> 
        <div dojoType="dojox.layout.ScrollPane" style="width:150px; height:300px;"
 orientation="vertical" id="vert"> 
 <table id="tableinvert"> 
                <tr><td><div dojoType="dijit.TitlePane" title="1" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
                <tr><td><div dojoType="dijit.TitlePane" title="2" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
                <tr><td><div dojoType="dijit.TitlePane" title="3" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
                <tr><td><div dojoType="dijit.TitlePane" title="4" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
                <tr><td><div dojoType="dijit.TitlePane" title="5" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
                <tr><td><div dojoType="dijit.TitlePane" title="6" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
                <tr><td><div dojoType="dijit.TitlePane" title="7" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
                <tr><td><div dojoType="dijit.TitlePane" title="8" sytle="width:100%; 
 height:100%;">title Pane content</div></td></tr> 
 </table> 
 </div> 
 </div> 
 </body>

请注意引用“<dojo_home>/dojox/layout/resources/ScrollPane.css”样式,否则在面板内容滚动时,不会显示滚动滑块。下面两图,图 15 为引用了 ScrollPane.css 样式的效果,图 16 为没有引用 ScrollPane.css 样式的效果。

图 15. ScrollPane: 引用 css 示例
图 15. ScrollPane: 引用 css 示例
图 16. ScrollPane: 未引用 css 示例
图 16. ScrollPane: 未引用 css 示例

图 16 中的滚动条并不能起到滑块的作用。本例在展示 ScrollPane 用法的同时,也展示了面板嵌套的方法。

下面介绍 ScrollPane 的一些常用属性:

orientation – String

定义了 ScrollPane 的滚动方向,有 vertical 和 horizontal 两种选择。需要注意的是,滚动的方向必须出现内容显示不下的情况,否则 SrollPane 的显示效果和 ContentPane 没有区别。


BorderContainer (dijit.layout.BorderContainer)

BorderContainer 是一个布局容器,它将容器内容分为 5 个区域:左 (left/leading), 右 (right/trailing), 上 (top), 下 (bottom), 中 (Center),如图所示。

图 17. BorderContainer: 基本示例
图 17. BorderContainer: 基本示例
清单 14. BorderContainer: 声明法示例
…
 <head> 
 <link rel="stylesheet" type="text/css" href="ibmdojo/dijit/themes/soria/soria.css"> 
 <style type="text/css"> 
 body, html { width:100%; height:100%; margin:0; padding:0 } 
 #borderContainer { width:100%; height:100% } 
 </style> 
 </head> 
 <script type="text/javascript" src="ibmdojo/dojo/dojo.js" djConfig="parseOnLoad: true"> 
 </script> 
 <script type="text/javascript"> 
 dojo.require("dijit.layout.ContentPane"); 
 dojo.require("dijit.layout.BorderContainer"); 
 dojo.require("dojo.parser"); 
 </script> 
 <body class="soria"> 
        <div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="true"
 liveSplitters="true" id="borderContainer" style="width: 400px; height: 300px;"> 
            <div dojoType="dijit.layout.ContentPane" splitter="true" region="leading"
 style="width: 100px;"> 
 Leading Region 
 </div> 
            <div dojoType="dijit.layout.ContentPane" splitter="true" region="trailing"
 style="width: 100px;"> 
 Tailing Region 
 </div> 
 <div dojoType="dijit.layout.ContentPane" splitter="true" region="center"> 
 Center Region 
 </div> 
            <div dojoType="dijit.layout.ContentPane" splitter="true" liveSplitters="true"
 region="top"> 
 Top Region 
 </div> 
 <div dojoType="dijit.layout.ContentPane" splitter="true" region="bottom"> 
 Bottom Region 
 </div> 
 </div> 
 </body>

五个区域可以分别嵌套各种容器与面板。如下图,顶部嵌套了 ScrollPane 面板

图 18. BorderContainer: 基本示例 2
图 18. BorderContainer: 基本示例 2

下面介绍一些 BorderContainer 常用的属性:

liveSpliter – Boolean

该属性定义了当用户拖动区域边界时,容器内区域大小是随着鼠标的移动改变 (liveSpliter = true),还是只有到鼠标松开时,才执行容器内区域大小的修改 (liveSpliter = false)。下图展示了该属性为 false 时拖动区域边界的情况:

图 19. BorderContainer:liveSpliter 属性示例
图 19. BorderContainer:liveSpliter 属性示例

gutters – Boolean

该属性定义了 BorderContainer 是否具有边界和留白。前面例子都是 gutter 为 true 的情况,下图展示了 gutter 属性为 false 的情况:

图 20. BorderContainer:gutter 属性示例
图 20. BorderContainer:gutter 属性示例

design – String

该属性定义了 BorderContainer 使用的布局方式。有“sidebar”, “headline”两种布局方式。选用 sidebar 布局方式时,左右区域与 BorderContainer 同高。选用 headline 布局方式时,上下区域与 BorderContainer 同宽。前面例子为 design=“sidebar”的示例,下图为 design=“headline”的示例。

图 21. BorderContainer:design 属性示例
图 21. BorderContainer:design 属性示例

spliter – Boolean 与 region – String

这两个属性是为嵌套在 BorderContainer 内部的区域定义的。region 定义内部区域位置 (top, bottom, left, right, leading, trailing, center),spliter 定义是否可以通过拖动区域边界修改区域大小。

以下简单介绍几种比较高级的布局方式,以便为实际的使用提供更多的选择。


高级布局方式

高级布局的方式的控件有:

  • GridContainer (dojox.layout.GridContainer)
  • AccordionContainer (dijit.layout.LayoutContainer)
  • TabContainer (dijit.layout.TabContainer)

GridContainer (dojox.layout.GridContainer)

GridContainer 是一种比较灵活的布局方式,允许用户根据自己的需要拖拽 grid 中的内容,每个 grid 中存放一个布局对象;可以通过一下函数设置容器的列数;acceptTypes 属性用来设置每个行可接受的对象类型,比如 ContentPane, TitlePane, ColorPalette, Calendar 等。

使用表述的方法创建该布局方式代码如下;

清单 15. GridContainer 声明法示例
 <div id="GC1" dojoType="dojox.layout.GridContainer" 
              nbZones="3"
              opacity="0.7" 
              allowAutoScroll="true" 
              hasResizableColumns="false"
              withHandles="true"
 acceptTypes="dijit.layout.ContentPane, dijit.TitlePane, dijit.ColorPalette, 
 dijit._Calendar"> 
 </div>

可以通过以下的 setColumns 函数根据用户的输入设置行数

清单 16. GridContainer 程序生成法示例
 function setColumns(){ 
		 GC1 = dijit.byId("GC1"); 
		 var nb = dojo.byId("nbCol").value; 
		 if(nb > 0){ 
			 GC1.setColumns(nb); 
		 } 
 }
图 22. GridContainer 示例
图 22. GridContainer 示例

AccordionContainer (dijit.layout.AccordionContainer)

位于 dijit.layout 包中 , 引用方法如下。

清单 17. AccordionContainer 引用方式
 dojo.require("dijit.layout.AccordionContainer");

AccordionContainer 顾名思义是像手风琴一样可以收缩的面板,这种方式比较适合单个 portal 的布局,小巧易用;也可以用于整个页面的布局。

图 23. AccordionContainer 示例
图 23. AccordionContainer 示例

使用表述的方法创建该布局方式代码如下;

清单 18. AccordionContainer 声明法示例
 <div dojoType="dijit.layout.AccordionContainer" 
 style="width: 400px; height: 300px; overflow: hidden"> 
 </div>

LayoutContainer (dijit.layout.LayoutContainer)

通过设置 layoutAlign="left"的属性来定义每个对象的具体位置;可以重复使用 layoutAlign = "left",这样的结果根据声明的先后顺序从左至右,从上至下的进行排列。这种布局方式比较简单,不需要考虑每个待布局对象的具体位置,只需要考虑对象之间的相对位置就可以了,比较适合于对整个页面进行布局。

图 24. LayoutContainer 示例
图 24. LayoutContainer 示例

使用表述的方法创建该布局方式代码如下;

清单 19. LayoutContainer 声明法示例
 <div dojoType="dijit.layout.LayoutContainer"
 style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"> 
 <div dojoType="dijit.layout.ContentPane" layoutAlign="left"
 style="background-color: #acb386; width: 100px;" tabindex="0"> 
 left 
       </div> 
 <div dojoType="dijit.layout.ContentPane" layoutAlign="right"
 style="background-color: #acb386;" tabindex="0"> 
 right 
 </div> 
 ……
 </div>

StackContainer (dijit.layout.StackContainer)

需要 dijit.layout.StackContainer 和 dijit.layout.StackController,引用如下;

清单 20. StackContainer 引用方法
 dojo.require("dijit.layout.StackContainer"); 
 dojo.require("dijit.layout.StackController");

这种布局分为控制器和面板两部分,控制器就是一组按钮,通过点击负责控制的按钮,在面板中显示被关注的内容。

之所以叫做栈,在于这种布局的控制器(也就是按钮)提供了前进和后退的功能,例如下图中的按钮 page1 之前有一个前进的控制器,点击可以激活 page3,如此循环,保持一定的顺序。

图 25. StackContainer 示例
图 25. StackContainer 示例

使用描述的方法创建该布局方式代码如下;

清单 21. StackContainer 声明法示例 -- 控制器部分
 <button dojoType="dijit.form.Button" id="previousPR"
       onClick="dijit.byId('myStackContainerPR').back()">&lt;</button> 
 <span dojoType="dijit.layout.StackController" containerId="myStackContainerPR"></span> 
 <button dojoType="dijit.form.Button" id="nextPR"
       onClick="dijit.byId('myStackContainerPR').forward()">&gt;</button>
清单 22. StackContainer 声明法示例 -- 布局部分
 <div id="myStackContainerPR" dojoType="dijit.layout.StackContainer"
       style="width: 90%; border: 1px solid #9b9b9b; height: 20em; 
              margin: 0.5em 0 0.5em 0; padding: 0.5em;"> 
……
 </div>

使用程序的方法动态创建该布局方式代码如下;

清单 23. StackContainer 程序生成法示例 -- 布局部分
 var container = new dijit.layout.StackContainer({ id: "sc" },"myStackContainer"); 
 container.addChild(new dijit.layout.ContentPane({ 
 title: "Page 1", 
 content: "Page 1"
 })); 
 container.addChild(new dijit.layout.ContentPane({ 
 title: "Page 2", 
 content: "Page 2"
 })); 
 // make the controller 
 var controller = new dijit.layout.StackController({containerId: "sc"}, "holder"); 
 // start 'em up 
 controller.startup(); 
 container.startup();
清单 24. StackContainer 程序生成法示例 -- HTML 部分
 <div id="myStackContainer" style="width: 90%; border: 1px solid #9b9b9b; 
                            height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;"> 
 </div>

TabContainer (dijit.layout.TabContainer)

Tab 目前在网页和应用程序中广泛使用,Dojo 也提供了 tab 的布局方式;TabContainer 位于 dijit.layout 中,引用方法如下。

清单 25. TabContainer 引用方法
 dojo.require("dijit.layout.TabContainer");

使用描述的方法创建该布局方式代码如下;

清单 26. TabContainer 声明法示例
 <div id="mainTabContainer" dojoType="dijit.layout.TabContainer" persist="true" 
                            tabStrip="true" style="width: 100%; height: 20em;"> 
 </div>

使用程序的方法动态创建该布局方式代码如下 :

清单 27. TabContainer 程序生成法示例
 var tc, cp1, cp2, cp3; 

 tc = new dijit.layout.TabContainer({style:'height:200px;width:500px;'}, 
                    dojo.byId('main')); 
 cp1 = new dijit.layout.ContentPane({title: 'Tab 1'}); 
 cp1.domNode.innerHTML = "Contents of Tab 1"; 
 tc.addChild(cp1); 

 cp2 = new dijit.layout.ContentPane({title: 'Tab 2'}); 
 cp2.domNode.innerHTML = "Contents of Tab 2"; 
 tc.addChild(cp2); 

 tc.startup();
图 26. TabContainer 示例
图 26. TabContainer 示例

也提供了纵向的 tab 布局方式;纵向的布局方式是通过设置属性来实现的,如下:

清单 28. TabContainer 中 tab 的布局方式示例
 <div dojoType="dijit.layout.TabContainer" style="width:500px;height:100px"
                                                  tabPosition="left-h"> 
 </div>
图 27. TabContainer 的 tab 布局方式示例
图 27. TabContainer 的 tab 布局方式示例

同样的,如果需要 tab 位于门户的下方,只要设置 tabPosition="bottom"即可。


结束语

Dojo 提供了灵活多样的布局方式,在实际开发过程中,需要根据实际的设计,选择符合场景的布局控件,才能使 web 界面更好的用户体验。

参考资料

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Web development
ArticleID=505231
ArticleTitle=使用 Dojo 提供的灵活多样的布局方式
publish-date=08052010