Border布局的所有框架都依赖于边框,有了边框才有了界限,进而混沌才出现日月山河,它缤纷的世界恰当地分割。可是当边框充彻每个角落的时候,你又会发现它也有讨厌的一面。
比如说嵌套使用控件经常遇到的边框叠加问题, 这个问题并不是有个border属性控制是否显示边框就能解决的,因为有时候我们要求显示左边边框,不显示右边边框,肿么办?难道每次都要用jQuery写一大堆代码去处理?
如果您有一定的css基础,并且懂一点美工,也会露几首PS,我想你大多会选择不要边框的region,所有的边边框采用自己的css实现,你可以用背景图模拟边框,只要你做的边框看起开比layout自己的边框更顺眼,您就没有理由保留layout各个region的边框了。
但是可惜了,我想80%的码农都是美工和css方面的二逼,所以您还是乖乖地使用layout的原始边框吧。
鉴于这个原因,我们迫切地需要能够对边框的灵活操作,panel就是基础,而panel里面的header和body才是最原子的东西,所以我们需要实现对panel的header和body两部分的边框灵活定制功能。
因为源码的错综复杂,我们当然是希望扩展的方式来达到目的。所以doBorderConf方法就这么诞生了。
实现代码:
1.在easyui.css和panle.css文件中均定义八个样式,该八个样式,分别对应四个边框的宽度为1和为0。
.left-border-no{ border-left-width:0px; } .right-border-no{ border-right-width:0px; } .top-border-no{ border-top-width:0px; } .bottom-border-no{ border-bottom-width:0px; } .left-border{ border-left-width:1px; } .right-border{ border-right-width:1px; } .top-border{ border-top-width:1px; } .bottom-border{ border-bottom-width:1px; }
2.扩展一个方法:doBorderConf用于配置panel的header和body的边框是否显示,主要是通过添加和删除之前定义的八个样式来实现。
$.extend($.fn.panel.methods, { doBorderConf: function(jq, params){ return jq.each(function(){ function _removeClass(jObj,className){ if(jObj.hasClass(className)) jObj.removeClass(className); }; function _removeAllClass(jObj){ var classArray = ['top-border-no','right-border-no','bottom-border-no','left-border-no', 'top-border','right-border','bottom-border','left-border']; for(var i=0; i<8; i++){ _removeClass(jObj,classArray[i]); } }; function _addAllClass(jObj,args){ for(var i=0; i < args.length; i++){ var classA = ""; switch(i){ case 0: classA = 'top-border'; break; case 1: classA = 'right-border'; break; case 2: classA = 'bottom-border'; break; case 3: classA = 'left-border'; break; default: classA = ''; break; } if(args[i]==0) classA += '-no'; jObj.addClass(classA); } }; if(params.header){ var borderList = params.header.split(' '); var hp = $(this).panel("header"); _removeAllClass(hp); _addAllClass(hp,borderList); } if(params.body){ var borderList = params.body.split(' '); var bp = $(this).panel("body"); _removeAllClass(bp); _addAllClass(bp,borderList); } $(this).panel('resize'); }); } });
使用方法:
//配置规则跟css的边框定义规则一样,分别为上右下左。 var borderConf = {header:'0 1 0 0',body:'1 1 0 0'}; $(selector).panel('doBorderConf',borderConf);
功能完善:
上面我们只是实现了设置边框的一个接口方法,这意味着我们如果想设置对边框的详细配置的话,必须要使用脚本去调用doBorderConf方法才行,这样是不是显得很不方便呢?
我们都知道easyui组件的很多属性都是可以直接写在DOM里面的,比如面板的title,fit等属性均可以卸载DOM中,那么我们对边框的详细配置是否也可以直接写在DOM中就能生效呢?
从实现上来讲,肯定是可以的,通过改源代码的话毫无疑问是可以解决这个需求的,但是我们为了尽量保证源码的纯洁性,有时候必须要考虑使用别的方法来实现。
我们注意到panel的onBeforeOpen很少被使用,所以我们可以更改默认的onBeforeOpen定义,让panel组件在onBeforeOpen事情中获取DOM中的边框配置属性,然后调用方法去实现对边框的配置。所以,在实现了doBorderConf方法的基础上,我们再做以下改进就可以实现进一步完善了:
1.首先重写panel的属性转换器。
为什么要覆写panel的属性转换器呢?主要原因还是为了尽量不修改源码,覆写的时候必须要把源码中支持的属性全部带上,同时增加我们需要的属性,其实把属性转换器覆写一次后,我们就可以方便地对其进行扩展了。
/** * 覆写panel的属性转换器,使其增加对某些属性的转换。 * @param {Object} target */ $.fn.panel.parseOptions = function(target){ var t = $(target); return { id: t.attr("id"), width: (parseInt(target.style.width) || undefined), height: (parseInt(target.style.height) || undefined), left: (parseInt(target.style.left) || undefined), top: (parseInt(target.style.top) || undefined), title: (t.attr("title") || undefined), iconCls: (t.attr("iconCls") || t.attr("icon")), cls: t.attr("cls"), headerCls: t.attr("headerCls"), bodyCls: t.attr("bodyCls"), tools: t.attr("tools"), href: t.attr("href"), loadingMessage: (t.attr("loadingMessage") != undefined ? t.attr("loadingMessage") : undefined), cache: (t.attr("cache") ? t.attr("cache") == "true" : undefined), fit: (t.attr("fit") ? t.attr("fit") == "true" : undefined), border: (t.attr("border") ? t.attr("border") == "true" : undefined), noheader: (t.attr("noheader") ? t.attr("noheader") == "true" : undefined), collapsible: (t.attr("collapsible") ? t.attr("collapsible") == "true" : undefined), minimizable: (t.attr("minimizable") ? t.attr("minimizable") == "true" : undefined), maximizable: (t.attr("maximizable") ? t.attr("maximizable") == "true" : undefined), closable: (t.attr("closable") ? t.attr("closable") == "true" : undefined), collapsed: (t.attr("collapsed") ? t.attr("collapsed") == "true" : undefined), minimized: (t.attr("minimized") ? t.attr("minimized") == "true" : undefined), maximized: (t.attr("maximized") ? t.attr("maximized") == "true" : undefined), closed: (t.attr("closed") ? t.attr("closed") == "true" : undefined), auto: (t.attr("auto") ? t.attr("auto") == "true" : true), //以下属性均为后扩展而来 borderHeader: (t.attr("borderHeader") != undefined ? t.attr("borderHeader") : undefined), borderBody: (t.attr("borderBody") != undefined ? t.attr("borderBody") : undefined) }; };
2.对扩展的两个属性设置默认值为null,并且覆写onBeforeOpen事件
$.fn.panel.defaults = $.extend({}, $.fn.panel.defaults, { borderHeader: null, borderBody: null, onBeforeOpen: function(){ var opts = $(this).panel('options'); var borderConf = {}; if (opts.borderHeader && opts.borderHeader != null) { borderConf.header = opts.borderHeader; } if (opts.borderBody && opts.borderBody != null) { borderConf.body = opts.borderBody; } if (borderConf.header || borderConf.body) { $(this).panel('doBorderConf', borderConf); } } });
3.使用方式:
<div class="easyui-panel" fit="true" title="My Panel" iconCls="icon-save" borderHeader="0 0 1 1" borderBody = "1 0 1 0"></div>
4.注意事项:
因为我们是覆写onBeforeOpen事件的默认值来达到打开面板前完成对边框的设置,所以说onBeforeOpen事件如果你在其它代码中定义的话就会覆盖我们覆写的默认值,从而导致对边框的设置无效,这一点必须是要明确的。
更新记录:
2012-07-12:
对于layout组件,可以定义各个region的style较为灵活地设置边框,即通过设置以下几个css属性设置各个region的边框:
border-top-width,border-right-width,border-bottom-width,border-left-width
管理员 世纪之光 : 2013年09月02日14:04:34 地下1层