DWZ并没有提供Layout布局组件 但是提供了良好的插件集成机制,这里花了点时间继承了一个第三方UI的布局组件即LigerUI Layout
文章最后会提供 SVN版代码 大家可以比较看如何集成的LigerUI Layout
详细:
1.1 添加JS库文件和CSS文件引用
在 index.html中:
<!-- ligerUI CSS 样式 -->
<link href="ligerUI/skins/Aqua/css/ligerui-layout.css" rel="stylesheet"
type="text/css" media="screen"/>
<!-- ligerUI 布局组件-->
<script src="ligerUI/js/core/base.js" type="text/javascript"></script>
<script src="ligerUI/js/plugins/ligerLayout.js" type="text/javascript"></script>
1.2 初始化layout、扩展、兼容修改
Dwz.ui.js 负责DWZ框架的初始化,具体就是遍历window中所有html元素
将需要的Html元素与DWZ(或者第三方框架)的JS效果进行绑定
PS:集成步骤:
A:ligerUI跟随DWZ加载
B:对两个框架进行兼容性修改
具体如下:
A:将ligerUI的 layout组件跟随DWZ初始化
目的:
具体就是将标记了class="ligerui_layout"的div 与 layout 组件的JS效果进行绑定
找到dwz的dwz.ui.js 在最后:
添加:
// 这里放其他第三方jQuery插件... //集成ligerUI layout 开始 集成代码参考的是dwz.ui.js 150行~239行 $(".ligerui_layout", $p).each(function(){ var $layout = $(this); /*注意 ligerUI layout 接受json参数后 不会进行类型转换 所以 int boolean必须自行转换*/ var opts = {}; if ($layout.attr("topHeight")) opts.topHeight = parseInt($layout.attr("topHeight")); if ($layout.attr("bottomHeight")) opts.bottomHeight = parseInt($layout.attr("bottomHeight")); if ($layout.attr("leftWidth")) opts.leftWidth = parseInt($layout.attr("leftWidth")); if ($layout.attr("centerWidth")) opts.centerWidth = parseInt($layout.attr("centerWidth")); if ($layout.attr("rightWidth")) opts.rightWidth = parseInt($layout.attr("rightWidth")); if ($layout.attr("InWindow")) opts.InWindow = Boolean($layout.attr("InWindow")); if ($layout.attr("heightDiff")) opts.heightDiff = parseInt($layout.attr("heightDiff")); if ($layout.attr("height")) opts.height = parseInt($layout.attr("height")); if ($layout.attr("isLeftCollapse")) opts.isLeftCollapse = Boolean($layout.attr("isLeftCollapse")); if ($layout.attr("isRightCollapse")) opts.isRightCollapse = Boolean($layout.attr("isRightCollapse")); if ($layout.attr("allowLeftCollapse")) opts.allowLeftCollapse = Boolean($layout.attr("allowLeftCollapse")); if ($layout.attr("allowRightCollapse")) opts.allowRightCollapse = Boolean($layout.attr("allowRightCollapse")); if ($layout.attr("allowLeftResize")) opts.allowLeftResize = Boolean($layout.attr("allowLeftResize")); if ($layout.attr("allowRightResize")) opts.allowRightResize = Boolean($layout.attr("allowRightResize")); if ($layout.attr("allowTopResize")) opts.allowTopResize = Boolean($layout.attr("allowTopResize")); if ($layout.attr("allowBottomResize")) opts.allowBottomResize = Boolean($layout.attr("allowBottomResize")); if ($layout.attr("space")) opts.space = parseInt($layout.attr("space")); if ($layout.attr("minLeftWidth")) opts.minLeftWidth = parseInt($layout.attr("minLeftWidth")); if ($layout.attr("minRightWidth")) opts.minRightWidth = parseInt($layout.attr("minRightWidth")); var $g = $layout.ligerLayout(opts); //利用Jquery 将该对象缓存到该html元素 以后如果在任何地方想操作该对象 //作用:可以随时调用该对象的方法 eg:根据页面变化需要resize一下 可以循环取出 //所有该对象 全部进行resize $layout.data("layoutObj",$g); //更改west部分的超链接为手动加载center ,使得layout center中的元素可以控制 west and east的关闭 //即:west部分的超链接 使用dwz手动局部刷新的办法 $("#xxxId").loadUrl(url,data, callback); //eg: // 手动超链接:<li><a href="demo/pagination/list_fool.html" target="layoutAjax" rel="fool_center" tname="name" tvalue="value" checked="true">第一级菜单项 ABC</a> // 按钮: <a href="javascript:void(0);" target="layoutControl" rel="rightCollapse" option="false" class="icon" ><span>打开右侧</span></a> //动态加载的center中 添加一个打开右侧的按钮 // PS:如下代码参考原型是dwz.ui.js 240行~253行 $("a[target=layoutAjax]", $layout).each(function(){ $(this).click(function(event){ var $this = $(this); var rel = $this.attr("rel"); if (rel) { var $rel = $("#"+rel); $rel.loadUrl($this.attr("href"), {}, function(){ $rel.find("[layoutH]").layoutH();//重新调整高度 $(window).trigger(DWZ.eventType.resizeGrid);//重新调整宽度 $rel.find("a[target=layoutControl]").each(function(){ var $openbtn = $(this); $openbtn.bind("click",function(event){ $g.setRightCollapse(false); event.preventDefault();//绑定 click的时候一定要在最后执行这一句否则会打开新页面 设置了 javascript:void(0);也不管用 }); }); }); } event.preventDefault(); }); }); }); //集成ligerUI Layout 结束
B: 添加需要的页面
一 、主菜单的超链接
<li><a href="ligerUI_layout1.html" target="navTab" rel="ligerUI_layout1" title="layout布局">集成ligerUI的Layout布局组件</a></li>
二、在上一步结果页中应用layout
<style type="text/css">
/*west标题位置垂直居中失效 这里修补一下*/
.l-layout-left .l-layout-header-inner {
line-height: 24px;
}
.l-layout-right .l-layout-header-inner {
line-height: 24px;
}
</style>
<div class="ligerui_layout" leftWidth="200" heightDiff="-36" isRightCollapse="true">
<div id="test_west" position="left" title="组织机构" layoutH="29">
<ul class="tree treeFolder collapse" >
<!--
<li><a href="demo/pagination/list_fool.html" target="ajax" rel="fool_center" tname="name" tvalue="value" checked="true">第一级菜单项 ABC</a>
-->
<li><a href="demo/pagination/list_fool.html" target="layoutAjax" [此处与dwz.ui.js中对应]rel="fool_center" tname="name" tvalue="value" checked="true">第一级菜单项 ABC</a>
<ul>
<li><a href="#" target="navTab" rel="dialog1" tname="name" tvalue="value" checked="true">第二级菜单项 A </a></li>
<li><a href="#">第二级菜单项 B </a></li>
<li><a href="#">第二级菜单项 C </a>
<ul>
<li><a href="#">第三级菜单项 A </a></li>
<li><a href="#">第三级菜单项 B </a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">第一级菜单项 B</a></li>
</ul>
</div>
<div id="fool_center" position="center" title="标题">
<h1 style="margin:200px;">组织部门管理</h1>
</div>
<div position="right" title="右侧"></div>
</div>
PS:
heightDiff 计算方法:
使用火狐查看 如果高度超出X像素 那么 添加 heightDiff="-X" 属性 反之同理
<!--[if !supportLists]-->三、<!--[endif]-->上一步layout center中 ajax异步加载的主数据页面示例
部分代码:
<div class="panelBar">
......
<li><a class="icon" href="javascript:void(0);"
target="layoutControl"
rel="rightCollapse"
option="false" [此处与dwz.ui.js中对应]><
span>打开右侧</span></a></li>
</ul>
</div>
C:兼容性问题
原因 :
<!--[if !supportLists]-->1. <!--[endif]-->dwz resize 与 ligerUI layout resize不同步导致
<!--[if !supportLists]-->2. <!--[endif]-->dwz与layout的resize都没有考虑到对方dom结构 resize仅仅考虑上层div的宽度或高度 然后重新计算自己的高与宽,两个插件集成以后dom 嵌套耦合在一起所以各自的resize方法都失效
详细问题 :dwz左侧菜单隐藏或再次打开时 右侧container内容区域的 宽度问题
上图是:左侧主菜单关闭后container最右侧出现大片空白
上图是:鼠标向右拖动左侧主菜单扩大主菜单宽度时 container右侧的 主数据区域没有自适应
问题分析:
左侧主菜单关闭与打开的JS控制代码是dwz.barDrag.js它在关闭与打开的时候调用了dwz的resize
左侧主菜单拖动扩大或缩小的JS控制代码也在这个文件中:
这里 $(window).trigger(DWZ.eventType.resizeGrid);//DWZ.eventType.resizeGrid 类似Java枚举在dwz.core.js中定义
意思是触发 window中注册的一个名为 resizeGrid的function。
最后通过全文查找该function定义在dwz.stable.js中,并绑定给window:
解决办法:
同理我们也向window注册一个ligerui layout resize函数 ,参考dwz的resize代码 这个function 应该循环所有的class=”ligerui_layout"” div对应的 layout布局对象 然后
调用形如 this.reize();的方法
通过分析 ligerui 的LigerLayout.js 发现布局对象一有变动(某个方向的div打开或关闭时)均会调用 _onResize() ,那么注册LigerUI Layout的resize方法如下:
一、定义Layout resize的对外访问函数
(目的是以便随时调用它来将所有Layout重新布局,这里是模仿DWZ :定义function后想window绑定)
在dwz初始化的时候 初始化ligerUI 后进行绑定
所以找到Dwz.ui.js
定义:
function _resizeLigerLayout(){ //重新布局dwz的table".ligerui_layout" $(".ligerui_layout").each(function(){ var $this = $(this); $this.data[这里取出的是Jquery缓存中的 与改div 对应的layout对象,缓存是在插件集成的时候添加的]("layoutObj")._onResize(); }); //重新布局ligerUI的 layout }
绑定:
function initEnv() { ....... setTimeout(function(){ initLayout(); initUI(); // navTab styles var jTabsPH = $("div.tabsPageHeader"); jTabsPH.find(".tabsLeft").hoverClass("tabsLeftHover"); jTabsPH.find(".tabsRight").hoverClass("tabsRightHover"); jTabsPH.find(".tabsMore").hoverClass("tabsMoreHover"); //ligerUI layout $(window).unbind("resizeLigerLayout").bind("resizeLigerLayout", [在此进行layout resize绑定]_resizeLigerLayout); }, 10); .................
二、按顺序调用dwz 、ligerUi-layout 的resize
现在我们可以随时调用这两个组件的resize方法进行重新布局,因为dwz出现问题的地方就是container中主数据区域的宽度,这个主数据区域的直接上级div是ligerUI的Layout
由此 resize的顺序是 先 ligerUI的Layout 进行重新布局 然后的dwz在布局好的上层div中重新布局(也就是调整主数据区域的宽度)
现在的问题就是按顺序调用这两个方法了:
需要调用的地方:
Dwz中:
dwz.barDrag.js
<!--[if !supportLists]-->1.<!--[endif]-->左侧主菜单打开时
2.左侧主菜单关闭时
3.左侧主菜单拖动改变左侧主菜单宽度时
LigerUI-Layout中:
LigerLayout.js
_onResize: function ()
{
.....
//liger layout 重新调整布局后 要调用dwz重新调整 (即调整container中主内容区域的宽度)
$(window).trigger(DWZ.eventType.resizeGrid);
}
另:SVN版本代码
后记:no zuo no die 国内的UI框架走了一遍最终还是选择EXT ,因为公司项目环境下EXT是最叫人省心省 力的 ,不过对于研究JS DWZ还是比较好的临摹素材 一个月多月 白白浪费 不说了都是泪