今天做了一个tabpanel实例,就是几个简单的功能:动态添加选项卡,右键菜单关闭其他和关闭当前,参考了网上一些例子和API,记录了一些问题:
1. 内容不显示原因: 没有设置 height属性 其实就是因为高度默认为0 显示了看不到
2. js错误 例外被抛出并未被捕获原因: 没有设置region属性(使用viewport)
3. 用viewport和用renderTo的区别:这俩属性都能把tabpanel渲染到页面上,区别就是viewport感觉是一种针对整天页面来说的布局管理器,要是你页面啥都没有,他就会把这个唯一的元素tabpanel放大到整个页面,同时width和height属性就不起作用了;renderTo这个属性就比较侧重于局部,就是说布局这个事由自己管理,所以可以自由的设置width和height,但是如果height属性忘了设置,那么内容就显示不了了,因为height默认为0,显示了看不到
放代码:
jsp部分:
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<link rel="stylesheet" href="<%=path %>/ext/resources/css/ext-all.css" type="text/css"></link>
<script type="text/javascript" src="<%=path %>/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="<%=path %>/ext/ext-all.js"></script>
<script type="text/javascript" src="<%=path %>/tab.js"></script>
</head>
<body>
<div id="tabdiv"></div>
</body>
</html>
老规矩 导入这仨文件!一个css 俩js
js部分:tab.js
var index=0;
var contentPanel;
Ext.onReady(function() {
contentPanel = new Ext.TabPanel({
renderTo: Ext.getBody(),
resizeTabs: true, //自动调整每个tab页的尺寸
minTabWidth: 100,//tab标签最小宽度(在页面缩放时)
tabWidth: 150,//正常状态下tab标签的宽度
activeTab:0, //默认显示的选项卡 0表示第一个
enableTabScroll: true,//设置为true 标签页带滚动动画(页面缩放)
width: 600,
height: 150,
region : 'center',//布局方式
defaults: { autoScroll: true },//默认带自动滚动
plugins: new Ext.ux.TabCloseMenu(),//右键菜单 这个属性还可以设置其他的功能 算是个插件属性 哈哈
tbar: [{ text: '新建Tab', iconCls: 'new-tab',handler:addTab}]//老面孔了 头部菜单 添加tab用的
});
//下面这个循环就是添加几个tab 懒得一个一个add了
while(1==1){
contentPanel.add({
id:'a'+index,
name:'aa'+index,
title:'aa'+index,
html:'<span>a'+index+'</span>',
closable:true,//带关闭按钮
draggable:true//能拖动
}).show();//不调用show方法无法显示
if(index>3) break;
index++;
}
// var viewport = new Ext.Viewport({//一种布局管理器
// layout : 'border',
// items : [{
// region : 'center',
// split : true,
// border : true,
// layout : 'border',
// items : [contentPanel]
// }]
// });
});
//添加选项卡的函数 这里注意id如果和之前的重复 那么会添加不上
function addTab(tab){
index++;
contentPanel.add({
title:'aa'+index,
id:'a'+index,
name:'aa'+index,
html:'aa'+index,
closable:true
});
}
//上面tabpanel用到的右键菜单 这个看起来有点小复杂 其实逻辑没那么麻烦
Ext.ux.TabCloseMenu=function(){
var contentPanelTemp,menu,ctxItem;//定义了三个临时变量 第一个就是tabpanel 第二个是菜单对象 三个就是被你右键的那个选项卡对象
this.init=function(tb){//初始化函数 据api说 tabpanel设置了plugins之后 会来自动执行这个init方法 这样重要的tabpanel对象就有了
contentPanelTemp=tb;//把tabpanel赋值给临时变量 后面对tabpanel的操作都用他了
contentPanelTemp.on("contextmenu",onContextMenu);//把菜单绑定上去
};
//绑定菜单的函数
function onContextMenu(ts,item,e){
ctxItem=item;//当前选中的选项卡
if(!menu){//如果菜单不存在 就给他创建个新的 这样只会在第一次的时候创建
menu=new Ext.menu.Menu([{//俩菜单 一个删除当前 一个删除其他
id:ts.id+'_id',
text:'关闭当前',
handler:function(){
contentPanel.remove(ctxItem);
}
},{
id:ts.id+'_close_id',
text:'关闭其他',
handler:function(){
contentPanelTemp.items.each(function(item){//这个函数是遍历用的 跟foreach一个意思 他的这个item其实就是当前遍历的对象
if(item.closable&&item!=ctxItem){//这里判断下 如果遍历的这个选项卡没关闭 并且 不是选中的选项卡 就给他删除掉
contentPanelTemp.remove(item);
}
});
}
}]);
}
var items=menu.items;//为了操作方便 放到了临时变量里
items.get(ts.id+'_id').setDisabled(!ctxItem.closable);//上面俩id 对号入座吧 这里说一下 disabled设置为true 则按钮不可用 而选项卡的closable为true 为显示状态 正好相反
if(contentPanelTemp.items.length==1){//不能全删除 必须留下一个
items.get(ts.id+'_id').setDisabled(true);
}
var otherallclose=true;//在只有一个选项卡的情况下 禁用关闭其他菜单选项
contentPanelTemp.items.each(function(temp){
if(temp!=item&&temp.closable){
otherallclose=false;//说明有1个以上的选项卡
return false;
}
});
//这里说一下 根据上面的逻辑 如果有显示并且不是被点击的那个选项卡(就是有一个以上的选项卡还显示) 就会进if 只要进了if otherallclose就是false 那么关闭其他菜单项就可以用 否则就是只有一个选项卡 自然就不用关闭其他了
items.get(ts.id+'_close_id').setDisabled(otherallclose);
menu.showAt(e.getPoint());//设置下坐标 也就是菜单出现的位置 发现要是弹了alert 位置就跑上面去了
}
};
注释都写了 仅供个人学习用途~ 如有雷同 纯属坑爹~