我们使用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;
}
本文详细解析了使用EasyUI创建面板时的实现机制,从原始div到最终面板的转换过程,包括主体内容、头部、标题、图标、操作按钮等元素的生成与布局。通过对比原始代码与EasyUI转换后的代码,揭示了EasyUI如何封装和扩展基本div以创建功能丰富的面板组件。
3051

被折叠的 条评论
为什么被折叠?



