分隔框(DividedBox)是一种布局类组件,可以分为两类,其中一类叫水平分隔框(HDividedBox),另一类叫垂直分隔框(VDividedBox)。水平分隔框会将其子级分为两列,而垂直分隔框则会将其子级分为两行。列与列之间以及行与行之间一般都会有一条可以拖动的用以改变子级组件大小的分隔条。下面仅以垂直分隔框为例来介绍此类组件是如何设计以及实现的。
成品组件用例
按照以往的设计经验,我们可以先写出想像中的成品组件用例,这将有助于我们后续的进一步的设计与实现。垂直分隔框既然是布局类的组件,那么它也一定是一个容器,该容器包含了上述我们提到的三种子级组件。为了使用方便,我们不应该把分隔框也写进去,分隔框应该由组件内部实现的。经过分析,我们得到下面的一个应用示例:
Example1: { css: "#example div { width: 80%; height: 80%; background: #AAA; }", xml: `<VDividedBox id="example"> <div id='top'/> <div id='bottom'/> </VDividedBox>`}该示例由一垂直分隔框组件包裹着两个 div 元素。这里分别设置两个 div 元素的宽高为父级的 80%,同时设置它们的背景色为灰色,这只是为了方便测试。另外,我们还需要考虑一个子框的初始比例分配问题。我们可以设置默认比例为 50:50,比例最好可以在组件实例化时静态指定,同时提供比例设置的动态接口。于是我们就有了下面的改进用例。
Example2: { css: "#example div { width: 80%; height: 80%; background: #AAA; }", xml: `<VDividedBox id="example" percent='30'> <div id='top'/> <div id='bottom'/> </VDividedBox>`, fun: function (sys, items, opts) { sys.top.on("click", e => sys.example.percent = 50); }}这个用例在垂直分隔框初始化时设置子框的初始比例分配为 30:70,当用户点击第一子框时,比例分配重新恢复为 50:50。不过要注意,这些比例分配指的是对排除分隔条所占用空间后剩余空间的比例分配。
设计与实现
现在让我们把注意力转移到组件的内部。我们先大致地确定组件基本的组成。直观地看,垂直分隔框显示包含三个组件部分:上子框部分、分隔条以及下子框部分。于是我们暂时可以得到下面的视图项部分:
VDividedBox: { xml: `<div id='hbox'> <div id='top'/> <div id='handle'/> <div id='bottom'/> </div>`}下一步,确保垂直分隔框组件实例的子级部分被正确地映射到上子框 top 以及下子框 bottom。方法是先让所有的子级元素对象全部被添加到上子框 top 中,然后在函数项中将下子级元素添加到下子框 bottom 中。
VDividedBox: { xml: `<div id='hbox'> <div id='top'/> <div id='handle'/> <div id='bottom'/> </div>`, map: {appendTo: "top" }, fun: function (sys, items, opts) { sys.bottom.elem().appendChild(this.last().elem()); }}
新闻热点
疑难解答
图片精选