2023年7月9日发(作者:)
如大量信息查看,当网页多窗口框架等都会用到,现在网上基于jquery Tab控件,其实也蛮多了,我以前用过的idtabs,就比较简单实用,也是比较灵活,但是对于复杂情况就要编码多些,太简单了些。还有就是jquery UI的里面的tab控件(没用过,我对jquery ui不太感冒),另外就是近期有点小火的easyui 中的tab控件,最早在javaeye上面看到的,界面还算漂亮,因为之前没开源,所以一直没跟进(好像最近开源了,前几天下载了看看,编码风格有点像prototype,看不出jquery的影子,不知道为什么叫jquery easyui呵呵,因为没太深入去学习,也不好做其他评价)。说了那么多,我们还是回到主题,因为种种原因不得不想着自己开发一个吧。于是就有了这篇,先来看看效果吧。
下图是单网页多窗口框架的效果图
下图是文末提供调用示例的效果截图。
大家可以看到了还是使用ExtJs的效果。其实CSS基本上是直接copy它的。我觉得它那个就非常好看,当然实际使用的时候大家有能力完全可以自己样子
第一 我们还是从HTML开始吧
注:我先控件的思路始终是先确定HTML结构,其次是样式,最终才是js实现的事件方法等。
其实看图我们就可以基本确定,tab控件主要有两个部分的html 一个是头,用于放tab选项卡的;另外一个是体,是内容的容器。那么就是两个Div容器,讲tab控件分成了header和body两部分。
其中header部分因为包含多选项卡 所以很容易想到ul +li的配合。来看一下header中的实际html结构
通过通过其中li即是一个选项卡,第一个a是关闭按钮,第二个a才是实际内容 通过嵌套标签来实现 左右中的背景图片设置(这个做法比较多见的)。当然能够有个好的效果,还是要靠CSS支持。必须对CSS有一定的了解。
Body的结构则更简单就是div嵌套div就就结束了。
第二 CSS样式表
因为CSS是copy EXTJS的我也就不多介绍了。大家可以看代码下载里面的实际代码,如果有问题可以再沟通交流
第三:开始编写JS了
老规矩先来一段完整的JS代码,大概有500行左右的代码,其实我换行比较勤快,实际的代码量其实还是比较少。
复制代码 代码如下:
; (function ($) {
$.el =function(option){
var dfop ={
items:[], //选项卡数据项 {id,text,classes,disabled,closeable,content,url,cuscall,onactive}
width:500,
height:400,
scrollwidth:100,//如果存在滚动条,点击按钮次每次滚动的距离
autoscroll:true //当选项卡宽度大于容器时自动添加滚动按钮
};
var headerheight=28;
$.extend(dfop, option);
var me =$(this).addClass("x-tab-panel").width();
innerwidth = -2;
//构建Tab的Html
var tcs= roll?"x-tab-scrolling-top":"";
var header = $("
style='width:"+innerwidth+"px;MozUserSelect:none;KhtmlUserSelect:none;'>
var stripwrap = $("
");var scrollerright = $("
");var scrollerleft = $("
");var ulwrap = $("
var stripspacer = $("
");var litemp =[];
for(var i=0,l=; i { var item =[i]; builditemlihtml(item,litemp); } ("
((""));
litemp =null;
(ulwrap);
if(roll)
{
(scrollerright).append(scrollerleft); }
(stripwrap).append(stripspacer);
var bodyheight=-headerheight;
var bodywrap = $("
");var body = $("
x-tab-panel-body-top'/>").css({width:innerwidth,height:bodyheight});
var bodytemp=[];
for(var i=0,l=; i var item =[i]; builditembodyhtml(item,bodytemp); } (("")).appendTo(bodywrap); (header).append(bodywrap); initevents(); function builditemlihtml(item,parray) { (" class='",ve?"x-tab-strip-active":"",ed?"x-tab-strip-disabled":"",ble?" x-tab-strip-closable":"",s?" x-tab-with-icon":"","'>"); (""); ("",,""); ("
}
function builditembodyhtml(item,parray)
{
("
("
("
if(){
("
}
else{
(t);
}
("
height='100%'
x-hide-display","'
class='x-tab-panel-body
x-panel-body-noborder'
width:",innerwidth,"px; }
function initevents()
{
//reset scoller
resetscoller();
scollerclick();
("li:not(.x-tab-edge)").each(function(e){
inititemevents(this);
});
}
function inititemevents(liitem)
{
(liitem);
(liitem);
(liitem);
}
function scollerclick()
{
if(roll)
{
(function(e){scolling("left")});
(function(e){scolling("right")});
}
}
function resetscoller()
{
if(roll)
{
var edge = ("li.x-tab-edge");
var eleft =on().left;
var sleft = ("scrollLeft");
if( sleft+eleft>innerwidth )
{
ss("x-tab-scrolling");
("visibility","visible");
("visibility","visible");
if(sleft>0)
{
Class("x-tab-scroller-left-disabled");
}
else{
ss("x-tab-scroller-left-disabled");
}
if(eleft>innerwidth) {
Class("x-tab-scroller-right-disabled");
}
else{
ss("x-tab-scroller-right-disabled");
}
rollnow =true;
}
else
{
Class("x-tab-scrolling");
e({"scrollLeft":0},"fast");
("visibility","hidden");
("visibility","hidden");
rollnow =false;
}
}
}
//
function scolling(type,max)
{
//debugger;
if(!roll || !rollnow)
{
return;
}
//debugger;
//var swidth = ("scrollWidth");
var sleft = ("scrollLeft");
var edge = ("li.x-tab-edge");
var eleft = on().left ;
if(type=="left"){
if(ss("x-tab-scroller-left-disabled"))
{
return;
}
if(width-20>0)
{
sleft -=width;
}
else{
sleft =0;
ss("x-tab-scroller-left-disabled");
} if(ss("x-tab-scroller-right-disabled"))
{
Class("x-tab-scroller-right-disabled");
}
e({"scrollLeft":sleft},"fast");
}
else{
if(ss("x-tab-scroller-right-disabled") && !max)
{
return;
}
//left + ;
if(max || (eleft>innerwidth && width-20<=innerwidth))
{
//debugger;
sleft = sleft+eleft-(innerwidth-38) ;
ss("x-tab-scroller-right-disabled");
// sleft = eleft-innerwidth;
}
else
{
sleft +=width;
}
if(sleft>0)
{
if(ss("x-tab-scroller-left-disabled"))
{
Class("x-tab-scroller-left-disabled");
}
}
e({"scrollLeft":sleft},"fast");
}
}
function scollingToli(liitem)
{
var sleft = ("scrollLeft");
var lleft = on().left;
var lwidth = idth();
var edge = ("li.x-tab-edge");
var eleft = on().left ;
if(lleft<=0)
{
sleft +=(lleft-2) ;
if(sleft<0) {
sleft=0;
ss("x-tab-scroller-left-disabled");
}
if(ss("x-tab-scroller-right-disabled"))
{
Class("x-tab-scroller-right-disabled");
}
e({"scrollLeft":sleft},"fast");
}
else{
if(lleft+lwidth>innerwidth-40)
{
sleft = sleft+lleft+lwidth+-innerwidth+40; // 40 =scrollerleft and scrollerrightwidth;
if(ss("x-tab-scroller-left-disabled"))
{
Class("x-tab-scroller-left-disabled");
}
//滚到最后一个了,那么就要禁用right;
if(eleft-(lleft+lwidth+-innerwidth+40)<=innerwidth)
{
ss("x-tab-scroller-right-disabled");
}
e({"scrollLeft":sleft},"fast");
}
}
();
}
function liswaphover()
{
$(this).hover(function(e){
if(!$(this).hasClass("x-tab-strip-disabled"))
{
$(this).addClass("x-tab-strip-over");
}
},function(e){
if(!$(this).hasClass("x-tab-strip-disabled"))
{
$(this).removeClass("x-tab-strip-over");
}
});
}
function closeitemclick()
{ if($(this).hasClass("x-tab-strip-closable"))
{
$(this).find("a.x-tab-strip-close").click(function(){
deleteitembyliid($(this).parent().attr("id"));
});
}
}
function liclick()
{
$(this).click(function(e){
var itemid = (7);
var curr = getactiveitem();
if( curr !=null && itemid == )
{
return;
}
var clickitem = getitembyid(itemid);
if(clickitem && ed)
{
return ;
}
if(curr)
{
$("#tab_li_"+).removeClass("x-tab-strip-active");
$("#tab_item_"+).addClass("x-hide-display");
ve =false;
}
if(clickitem)
{
$(this).addClass("x-tab-strip-active");
$("#tab_item_"+).removeClass("x-hide-display");
if()
{
var cururl = $("#tab_item_frame_"+).attr("src");
if(cururl =="about:blank")
{
$("#tab_item_frame_"+).attr("src",);
}
}
else if(l && !led)
{
var panel = $("#tab_item_content_"+);
var ret = l(this,clickitem,panel);
led =true; if(ret) //如果存在返回值,且不为空
{
t = ret;
(ret);
}
}
ve =true;
if(ve)
{
(this,clickitem);
}
}
});
}
//获取当前活跃项
function getactiveitem()
{
for(var i=0,j=;i { if([i].isactive) { return [i]; break; } } return null; } //根据ID获取Item数据 function getitembyid(id) { for(var i=0,j=;i { if([i].id == id) { return [i]; break; } } return null; } function getIndexbyId(id) { for(var i=0,j=;i { if([i].id == id) { return i; break; } } return -1; } //添加项 function addtabitem(item) { var chkitem =getitembyid(); if(!chkitem){ var isactive =ve; ve =false; var lastitem = [-1]; (item); var lastli = $("#tab_li_"+); var lastdiv = $("#tab_item_"+); var litemp =[]; var bodytemp = []; builditemlihtml(item,litemp); builditembodyhtml(item,bodytemp); var liitem = $(("")); var bodyitem= $(("")); (liitem); (bodyitem); //事件 var li = $("#tab_li_"+); inititemevents(li); if(isactive) { (); } resetscoller(); scolling("right",true); } else{ alert("指定的tab项已存在!"); } } function openitemOrAdd(item,allowAdd) { var checkitem = getitembyid(); if(!checkitem && allowAdd ) { addtabitem(item); } else{ var li = $("#tab_li_"+); scollingToli(li); } } //移除一个tab 项 function deleteitembyliid(liid) { var id= (7); $("#"+liid).remove(); $("#tab_item_"+id).remove(); var index = getIndexbyId(id); if(index>=0) { var nextcur; if(index < -1) { nextcur = [index+1]; } else if(index>0){ nextcur = [index-1]; } if(nextcur) { $("#tab_li_"+).click(); } (index,1); resetscoller(); scolling("right",true); } } function resize(width,height) { if(width == && height ==) { return; } if(width){ =width}; if(height){ =height;} innerwidth = width-2; bodyheight=-headerheight; ("width",); ("width",innerwidth); ({width:innerwidth,height:bodyheight}); for(var i=0,j=;i { var item =[i]; $("#tab_item_"+).css({width:innerwidth}); $("#tab_item_content_"+).css({width:innerwidth,height:bodyheight}); } resetscoller(); } //设置选项卡项是否disabled function setdisabletabitem(itemId,disabled) { var chitem= getitembyid(itemId); if(!chitem || ed ==disabled) { return; } if(disabled) { ed =true; $("#tab_item_"+).addClass("x-tab-strip-disabled"); } else{ ed =false; $("#tab_item_"+).removeClass("x-tab-strip-disabled"); } } me[0].tab = { addtabitem:addtabitem, opentabitem:openitemOrAdd, resize:resize, setdisabletabitem:setdisabletabitem }; }; $.item =function(item) { if(this[0].tab) { return this[0].item(item); } return false; } $.bitem =function(item,orAdd) { if(this[0].tab) { return this[0].bitem(item,orAdd); } return false; } $.tabpanel =function(w,h) { if(this[0].tab) { return this[0].(w,h); } return false; } $.abletabitem =function(itemId,disabled) { if(this[0].tab) { return this[0].abletabitem(itemId,disabled); } return false; } })(jQuery); 接着我们来一步一步来分析我的实现,开始还是编写jQuery控件的“模板”,关于为什么要这么写,请参考这篇的说明 复制代码 代码如下: ; (function ($) { $.el =function(option){ }; )(jQuery); 接着就是编写默认参数 复制代码 代码如下:var dfop ={ items:[], //选项卡数据项 {id,text,classes,disabled,closeable,content,url,cuscall,onactive} width:500, height:400, scrollwidth:100,//如果存在滚动条,点击按钮次每次滚动的距离 autoscroll:true //当选项卡宽度大于容器时自动添加滚动按钮 }; 默认参数还是比较简单,我已加上了注释,其中就是item数组的项麻烦些,不过我相信大家通过字面的意思就已经知道大半了,我还是描述一下吧:id 即标示,必须唯一、text显示的文本、classes 特定的样式,如效果中的主页,我加了个图标,就通过此属性实现、disabled 是否禁用、closeable 是否可关闭、 content 和url 和cuscall 三个只要设置其中之一即可,content就是实际的内容html、url标示内容为网页,自动往内容中添加iframe,cuscall则是自定义,即内容显示什么有cuscall执行的结果来决定,可通过此属性来实现异步content内容。 onactive是指当tab项被激活时触发的事件。 是一个接受item内容的函数,详见demo 参数设置完了,通过外部传递的参数来更新默认的参数: $.extend(dfop, option); 接着就是构建html的部分,这部分比较长,我就不重复贴代码了。 当我们把html构建完成之后,就要给html元素添加事件,包括 选项卡的点击事件,左移按钮,右移按钮的点击事件,选项卡的鼠标hover效果事件等。 复制代码 代码如下: function initevents() { //reset scoller resetscoller(); //设置默认是否出现滚动掉 scollerclick(); //滚动条的点击事件,如果存在的话 ("li:not(.x-tab-edge)").each(function(e){ inititemevents(this); //给每个选项卡 添加事件 }); } function inititemevents(liitem) { (liitem); //选项卡的鼠标hover效果 (liitem); //选项卡的点击事件 (liitem); // 点击关闭按钮的事件 } 至于事件的实现,其实一个个来做,各个击破也就简单了。主要繁琐在控制滚动按钮的出现和禁用等的处理上,其他点击事件等都比较简单。 最后就是公开方法,和为了公开这些方法来编写一些内部方法,这个tabpanel自然还是比较简单易用,同时扩展性。大家可以根据实际的需求做些调整,当然现在的功能应该也满足大部分的要求了。 最后来看一下公开了哪些方法: 1:动态 新增tab项的方法,即通过js动态新增tab项,这里其实就是对items数据的维护,然后重新调用tabitem的输出html方法,最后单独为其设置事件。简单 2:选中或者新增。这也是通过js调用的方法,是对上一方法的扩展,即可通过js让某个tab项激活,如果该项不存在则通过参数来新增该选项卡 3:重新设置tabpanel的大小,即通过js重新设置tabpanel的大小,这个在窗口大小变化时调用,非常实用哦。 4:设置某项为禁用,通过js方法设置某项tabitem状态为禁用。 最后大家可以通过 代码 包括之前控件的实例,我已经提供了一个压缩包,但是我更推荐大家实用SVN获取最新代码。因为有的时候一些小的变动我就不发文告知了。 详细出处参考:/article/
发布者:admin,转转请注明出处:http://www.yc00.com/news/1688851019a176567.html
评论列表(0条)