<>强分隔框(DividedBox) 强>是一种布局类组件,可以分为两类,其中一类叫水平分隔框(HDividedBox),另一类叫垂直分隔框(VDividedBox)。水平分隔框会将其子级分为两列,而垂直分隔框则会将其子级分为两行,列与列之间以及行与行之间一般都会有一条可以拖动的用以改变子级组件大小的分隔条。下面仅以垂直分隔框为例来介绍此类组件是如何设计以及实现的。
<强>成品组件用例
强>
按照以往的设计经验,我们可以先写出想像中的成品组件用例,这将有助于我们后续的进一步的设计与实现。垂直分隔框既然是布局类的组件,那么它也一定是一个容器,该容器包含了上述我们提到的三种子级组件。为了使用方便,我们不应该把分隔框也写进去,分隔框应该由组件内部实现的。经过分析,我们得到下面的一个应用示例:
例二:{ div css:“#例子{宽度:80%;高度:80%;背景:# AAA级;}”, xml: ' & lt; VDividedBox id=袄印北? & lt; div id=岸ゼ丁?比; & lt; div id=暗撞俊?比; & lt;/VDividedBox> } >之前该示例由一垂直分隔框组件包裹着两个div元素。这里分别设置两个div元素的宽高为父级的80%,同时设置它们的背景色为灰色,这只是为了方便测试。另外,我们还需要考虑一个子框的初始比例分配问题。我们可以设置默认比例为50:50,比例最好可以在组件实例化时静态指定,同时提供比例设置的动态接口。于是我们就有了下面的改进用例。
Example2: { div css:“#例子{宽度:80%;高度:80%;背景:# AAA级;}”, xml: ' & lt; VDividedBox id=袄印卑俜直?' 30的祝辞 & lt; div id=岸ゼ丁?比; & lt; div id=暗撞俊?比; & lt;/VDividedBox>” 乐趣:函数(sys、物品选择){ sys.top。(“点击”,e=比;sys.example。%=50); } }这个用例在垂直分隔框初始化时设置子框的初始比例分配为30:70,当用户点击第一子框时,比例分配重新恢复为50:50。不过要注意,这些比例分配指的是对排除分隔条所占用空间后剩余空间的比例分配。
<强>设计与实现
强>现在让我们把注意力转移到组件的内部。我们先大致地确定组件基本的组成。直观地看,垂直分隔框显示包含三个组件部分:上子框部分,分隔条以及下子框部分。于是我们暂时可以得到下面的视图项部分:
VDividedBox: { xml:“& lt; div id=癶box”比; & lt; div id=岸ゼ丁?比; & lt; div id=按怼?比; & lt; div id=暗撞俊?比; & lt;/div> } >之前下一步,确保垂直分隔框组件实例的子级部分被正确地映射到上子框顶部以及下子框底部。方法是先让所有的子级元素对象全部被添加到上子框中,然后在函数项中将下子级元素添加到下子框底部中。
VDividedBox: { xml:“& lt; div id=癶box”比; & lt; div id=岸ゼ丁?比; & lt; div id=按怼?比; & lt; div id=暗撞俊?比; & lt;/div>” 地图:{appendTo:“顶级”}, 乐趣:函数(sys、物品选择){ .elem sys.bottom.elem () .appendChild (this.last () ()); } } >之前现在让我们来考虑下视图项的样式,对于顶层div元素,我们设置其定位方式为相对定位。对于子级的三个元素则设置为绝对定位。另外,把分隔条高度设置为5 px。
VDividedBox: { css:“# hbox{:相对;宽度:100%;高度:100%;box-sizing: border-box;} #{面上:0;高度:30%;{}#底部底:0;高度:钙(70% - 5 px);} #,#{底部左:0;右:0;位置:绝对的;} #处理{高度:5 px;宽度:100%;位置:绝对的;左:0;上图:30%;z - index: 11;光标:row-resize;}', xml:“& lt; div id=癶box”比; & lt; div id=岸ゼ丁?比; & lt; div id=按怼?比; & lt; div id=暗撞俊?比; & lt;/div>” 地图:{appendTo:“顶级”}, 乐趣:函数(sys、物品选择){ .elem sys.bottom.elem () .appendChild (this.last () ()); } } >之前最后让我们看看如何响应分隔条的拖动事件,从而更改子框的分配比例。我们需要定义一个改变子框比例的函数,同时侦听分隔条的拖拽事件。下面是我们的一个实现。
VDividedBox: {//视图项同上 地图:{格式:{“int”:“百分比”},appendTo:“顶级”}, 乐趣:函数(sys、物品选择){ var=50百分比; sys.handle。(“dragstart”功能(e) { sys.hbox。(“dragover dragover); }); sys.hbox。(“拖动结束”,函数(e) { e.stopPropagation (); sys.hbox。(“dragover dragover); }); 函数dragover (e) { e.preventDefault (); setPercent (e。直pageY - sys.hbox.offset()上)/sys.hbox.height () * 100); } 函数setPercent(价值){ sys.handle。css(“顶级”、价值+“%”); sys.top。css(“高度”,价值+“%”); sys.bottom。css(“高度”、“钙(" +(100 -值)+ % - 5 px) "); } setPercent(选择。% | | %); .elem sys.bottom.elem () .appendChild (this.last () ()); 返回Object.defineProperty(“百分比”{},{得到:()=比;{返回%},设置:setPercent}); } }xmlplus组件设计系列之分隔框(DividedBox) (8)