我们使用easyui的panel时,只需要指定一个div和相关的属性就可以生成带操作按钮的panel。
原始div的代码为:
<div id="p" class="easyui-panel" style="width:500px;height:200px;padding:10px;"
title="My Panel" iconCls="icon-save"
collapsible="true" minimizable="true"
maximizable=true closable="true">
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
</div>
而经过easyui转换后的代码为:
<div class="panel" style="display: block; width: 500px;">
<!--头-->
<div class="panel-header" style="width: 488px;">
<!--标题并且带有图标-->
<div class="panel-title panel-with-icon">My Panel</div>
<!--图标-->
<div class="panel-icon icon-save"></div>
<!--操作小按钮-->
<div class="panel-tool">
<div class="panel-tool-close"></div>
<div class="panel-tool-max"></div>
<!--还原按钮
<div class="panel-tool-max panel-tool-restore"></div>
-->
<div class="panel-tool-min"></div>
<div class="panel-tool-collapse"></div>
<!--展开按钮
<div class="panel-tool-collapse panel-tool-expand"></div>
-->
</div>
</div>
<!--主体-->
<div closable="true" maximizable="true" minimizable="true" collapsible="true" iconcls="icon-save" title="" style="width: 478px; height: 152px; padding: 10px;" class="easyui-panel panel-body" id="p">
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
</div>
</div>
通过对比可以发现,通过easyui转换后的<!--主体-->div和是原始div代码一样只是添加了一些类如panel-body,并改变div宽度和高度。
根据源码可以分析出easyui的panel生成步骤如下:
1.根据传入的参数来决定是执行相应的方法还是进行初始化
2.初始化时对原始的div进行了包装,包装函数为wrapPanel(this)
//封装panel function wrapPanel(target){ var panel = $(target).addClass('panel-body').wrap('<div class="panel"></div>').parent(); panel.bind('_resize', function(){ var opts = $.data(target, 'panel').options; //如果fit=true就自动适应 if (opts.fit == true){ setSize(target); } //取消默认的事件 return false; }); return panel; }
此函数主要是在原始div增加了panel-body类,并外部包装了一个<div class="panel"></div>
生成后的html代码为
<div class="panel">
<!--主体-->
<div closable="true" maximizable="true" minimizable="true" collapsible="true" iconcls="icon-save" title="" style="width: 478px; height: 152px; padding: 10px;" class="easyui-panel panel-body" id="p">
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
</div>
</div>
3.添加panel头和标题,调用的函数addHeader(this);
具体代码如下:
//添加表头函数 function addHeader(target){ var opts = $.data(target, 'panel').options; var panel = $.data(target, 'panel').panel; //删除原来的表头 removeNode(panel.find('>div.panel-header')); //如果有标题且包含表头 if (opts.title && !opts.noheader){ //把<div class="panel-header"><div class="panel-title">标题</div></div>前置到panel中 var header = $('<div class="panel-header"><div class="panel-title">'+opts.title+'</div></div>').prependTo(panel); /*如果有iconCls属性,即: <div class="panel-header"> <div class="panel-title panel-with-icon">标题</div> <div class="panel-icon icon-save"></div> </div> */ if (opts.iconCls){ //在<div class="panel-title">中加panel-with-icon类 header.find('.panel-title').addClass('panel-with-icon'); //在<div class="panel-header">尾部加<div class="panel-icon"></div> $('<div class="panel-icon"></div>').addClass(opts.iconCls).appendTo(header); } //在<div class="panel-header">尾部加<div class="panel-tool"></div> var tool = $('<div class="panel-tool"></div>').appendTo(header); /*如果有closable属性,即: <div class="panel-tool"> <div class="panel-tool-close"></div> </div> */ if (opts.closable){ //在<div class="panel-tool"></div>尾部加<div class="panel-tool-close"></div>,并添加click监听 $('<div class="panel-tool-close"></div>').appendTo(tool).bind('click', onClose); } //最大化 if (opts.maximizable){ $('<div class="panel-tool-max"></div>').appendTo(tool).bind('click', onMax); } //最小化 if (opts.minimizable){ $('<div class="panel-tool-min"></div>').appendTo(tool).bind('click', onMin); } //折叠 if (opts.collapsible){ $('<div class="panel-tool-collapse"></div>').appendTo(tool).bind('click', onToggle); } //如果定义了tools属性 if (opts.tools){ for(var i=opts.tools.length-1; i>=0; i--){ var t = $('<div></div>').addClass(opts.tools[i].iconCls).appendTo(tool); if (opts.tools[i].handler){ t.bind('click', eval(opts.tools[i].handler)); } } } /*对按钮图标hover进行监听,即对 <div class="panel-tool-close"></div> <div class="panel-tool-max"></div> <div class="panel-tool-min"></div>,进行监听 */ tool.find('div').hover( function(){$(this).addClass('panel-tool-over');}, function(){$(this).removeClass('panel-tool-over');} ); //删除body中没有panel-body-noheader的样式 panel.find('>div.panel-body').removeClass('panel-body-noheader'); } else { //否则就在div.panel-body加panel-body-noheader样式 panel.find('>div.panel-body').addClass('panel-body-noheader'); } //折叠 function onToggle(){ if ($(this).hasClass('panel-tool-expand')){ expandPanel(target, true); } else { collapsePanel(target, true); } return false; } //最小化 function onMin(){ minimizePanel(target); return false; } //最大化 function onMax(){ if ($(this).hasClass('panel-tool-restore')){ restorePanel(target); } else { maximizePanel(target); } return false; } //关闭 function onClose(){ closePanel(target); return false; } }
其本质就是生成按钮div,并绑定相应的操作函数,具体的我在函数里边都已经添加注释。
4.根据状态打开和关闭panel,至此panel渲染完毕
源代码中发现东东:
1.在panel中所有的事件,不是通过bind和trigger来触发的,而是直接通过函数调用来触发的,触发的方式为
opts.onMaximize.call(target);和opts.onResize.apply(target, [opts.width, opts.height]);
2.panel-body的样式可以看出技巧,先设置所有border的样式,完了让顶部的宽度为0px
.panel-body{
overflow:auto;
border:1px solid #99BBE8;
border-top-width:0px;
}