在这个示例中,有时候分隔条会失灵,子框比例不再随着分隔条位置而出现变化。问题出在文本域对拖拽事件进行了劫持,导致我们我组件内部收不到响应的事件。我们需要做些补丁才行。
VDividedBox: { css: "#hbox { position:relative; width:100%; height:100%; box-sizing: border-box; }\ #top { top: 0; height: 30%; } #bottom { bottom: 0; height: calc(70% - 5px); }\ #top,#bottom { left: 0; right: 0; position: absolute; }\ #handle { height: 5px; width: 100%; position:absolute; left:0; top: 30%; z-index:11; cursor:row-resize; }\ #mask { width: 100%; height: 100%; position: absolute; display: none; z-index: 10; }", xml: "<div>\ <div/>\ <div draggable='true'/>\ <div/>\ <div/>\ </div>", map: { format: {"int": "percent"}, appendTo: "top" }, fun: function (sys, items, opts) { var percent = 50; sys.handle.on("dragstart", function (e) { sys.mask.show(); sys.hbox.on("dragover", dragover); }); sys.hbox.on("dragend", function (e) { sys.mask.hide(); e.stopPropagation(); sys.hbox.off("dragover", dragover); }); function dragover(e) { e.preventDefault(); setPercent((e.pageY - sys.hbox.offset().top) / sys.hbox.height() * 100); } function setPercent(value) { sys.handle.css("top", value + "%"); sys.top.css("height", value + "%"); sys.bottom.css("height", "calc(" + (100 - value) + "% - 5px)"); } setPercent(opts.percent || percent); sys.bottom.elem().appendChild(this.last().elem()); return Object.defineProperty({}, "percent", {get: () => {return percent}, set: setPercent}); } }
为了解决问题,我们在组件中引用了额外的 div 元素对象 mask,此元素默认是不显示的。当拖动开始时,它才会覆盖住子框以及分隔条,而拖动一结束,它又隐藏掉。这样就避免了文本域对拖拽事件的劫持。
结合水平分隔框使用
我们有了上述垂直分隔框的设计经验,搞个水平分隔框也就不是什么难事了,这里就不列出来了。这里主要是给出一个综合使用水平分隔框和垂直分隔框的示例。当然的设计之初,我们并没有想到要这么使用。
Example4: { css: `#example div { width: 100%; height: 100%; }`, xml: `<HDividedBox> <VDividedBox percent='30'> <div/><div/> </VDividedBox> <VDividedBox percent='30'> <div/><div/> </VDividedBox> </HDividedBox>` }
这个示例主要用于展示当分隔框嵌套使用时的表现。该示例包含一个水平分隔框,该水平分隔框又包含两个垂直分隔框,这种布局在不少编辑器中是很常见的,我们这里已经简单高效地把它实现了。
本系列文章基于 xmlplus 框架。如果你对 xmlplus 没有多少了解,可以访问 。这里有详尽的入门文档可供参考。