such as a large number of information to view, when the Web page more than a window frame will be used, and now on the internet based on the JQuery tab control, in fact, quite a lot, I used to idtabs, it is more simple and practical, but also more flexible, but for the complexity of the code more, too simple There is the tab control in the jquery UI (no, I'm not too cold on the jquery UI), and the tab control in the Easyui of the recent little fire, the first to see on the Javaeye, the interface is pretty, because there was no open source, So has not followed up (as if recently open source, a few days ago to download a look, coding style is a bit like prototype, do not see the shadow of jquery, do not know why is called jquery Easyui hehe, because not too deep to learn, also not good to do other evaluations). Say so much, we still return to the topic, because of various reasons have to think of ourselves to develop a bar. So there is this article, first to see the effect of it.
The following figure is a single page multi-window frame effect diagram
The following figure is a screenshot of the effect provided at the end of the article for invoking the example.
You can see or use the effect of ExtJS. In fact, CSS is basically directly copy it. I think it's very good-looking, of course, when the actual use of the people have the ability to fully look like
First, let's start with the HTML.
Note: I first control the idea is always first to determine the HTML structure, followed by the style, the final is JS implementation of the event methods.
Actually look at the picture we can basically determine that the tab control mainly has two parts of the HTML is a header, for the Tab tab, the other is the body, is the content of the container. Then there are two div containers, and the tab control is divided into header and body parts.
Where the header part because it contains multiple tabs, so it is easy to think of the UL +li cooperation. Take a look at the actual HTML structure in the header
Through which Li is a tab, the first A is the Close button, the second A is the actual content through nested tags to achieve the left and right background picture settings (this practice is more common). Of course can have a good effect, or rely on CSS support. Must have a certain understanding of CSS.
The body structure is simpler is the div nested div is over.
Second CSS style sheet
Because the CSS is copy ExtJS I will not introduce more. You can see the code download the actual code, if there are problems can be communicated
The third: start writing JS
The old rules first to a complete JS code, about 500 lines around the code, in fact, I am more diligent, the actual amount of code is actually relatively small.
Copy Code code as follows:
; (function ($) {
$.fn.tabpanel =function (option) {
var Dfop ={
Items:[],//Tab data item {id,text,classes,disabled,closeable,content,url,cuscall,onactive}
WIDTH:500,
height:400,
scrollwidth:100,//If there is a scroll bar, click the button every time the scroll distance
Automatically add scroll button when autoscroll:true//tab width is larger than container
};
var headerheight=28;
$.extend (DFOP, option);
var me =$ (This). addclass ("X-tab-panel"). Width (dfop.width);
Innerwidth = dfop.width-2;
HTML to Build tab
var tcs= dfop.autoscroll? " X-tab-scrolling-top ":" ";
var Header = $ ("<div class= ' x-tab-panel-header x-unselectable" +tcs+ "' unselectable= ' on ' style= ' width:" +innerwidth+ "PX; Mozuserselect:none; Khtmluserselect:none; ' ></div> ");
var stripwrap = $ ("<div class= ' X-tab-strip-wrap '/>");
var scrollerright = $ ("<div class=" x-tab-scroller-right x-unselectable ' style= ' height:24px; Visibility:hidden; Mozuserselect:none; Khtmluserselect:none ' unselectable= ' on '/> ');
var scrollerleft = $ ("<div class=" x-tab-scroller-left x-unselectable ' style= ' height:24px; Visibility:hidden; Mozuserselect:none; Khtmluserselect:none ' unselectable= ' on '/> ');
var ulwrap = $ ("<ul class= ' X-tab-strip x-tab-strip-top ' ></ul>");
var stripspacer = $ ("<div class= ' X-tab-strip-spacer '/>");
var litemp =[];
for (var i=0,l=dfop.items.length; i<l; i++)
{
var item =dfop.items[i];
Builditemlihtml (item,litemp);
}
Litemp.push ("<li class= ' X-tab-edge '/><div class= ' x-clear ' ></div>");
Ulwrap.html (Litemp.join (""));
Litemp =null;
Stripwrap.append (Ulwrap);
if (Dfop.autoscroll)
{
Header.append (Scrollerright). Append (Scrollerleft);
}
Header.append (Stripwrap). Append (Stripspacer);
var bodyheight=dfop.height-headerheight;
var BodyWrap = $ ("<div class= ' X-tab-panel-bwrap '/>");
var BODY = $ ("<div class= ' x-tab-panel-body x-tab-panel-body-top '/>"). css ({width:innerwidth,height:bodyheight} );
var bodytemp=[];
for (var i=0,l=dfop.items.length; i<l; i++) {
var item =dfop.items[i];
Builditembodyhtml (item,bodytemp);
}
Body.html (Bodytemp.join ("")). Appendto (BodyWrap);
Me.append (header). append (BodyWrap);
Initevents ();
function builditemlihtml (Item,parray)
{
Parray.push ("<li id= ' Tab_li_", item.id, "' class= '", item.isactive?) X-tab-strip-active ":" ", item.disabled?" X-tab-strip-disabled ":", item.closeable? "x-tab-strip-closable": "", item.classes? "X-tab-with-icon": "", ">");
Parray.push ("<a class= ' x-tab-strip-close ' onclick= ' return false; ') /> ");
Parray.push ("<a class= ' x-tab-right ' onclick= ' return false; ' href= '] ' >");
Parray.push ("<em class= ' x-tab-left ' ><span class= ' x-tab-strip-inner ' ><span ') class= ' X-tab-strip-text '" , item.classes| | "", "' >", Item.text, "</span></span></em>");
Parray.push ("</a></li>");
}
function builditembodyhtml (Item,parray)
{
Parray.push ("<div class= ' X-panel x-panel-noborder", item.isactive? "": "X-hide-display", "' id= ' tab_item_", item.id , "' style= ' width:", innerwidth, "px ' >");
Parray.push ("<div class= ' X-panel-bwrap ' >");
Parray.push ("<div class= ' x-panel-body x-panel-body-noheader x-panel-body-noborder ' id= ' Tab_item_content_ '), Item.id, "' style= ' position:relative; Width: ", innerwidth," PX; Height: ", bodyheight," PX; Overflow:auto; ' > ");
if (Item.url) {
Parray.push ("<iframe name= ' Tab_item_frame_", item.id, "' width= ' 100% ' height= ' 100% ' ' id= ', ' tab_item_frame_ '), Item.id, "' src= ' about:blank ' frameborder= ' 0 '/>");
}
else if (Item.cuscall) {
Parray.push ("<div class= ' Loadingicon '/>");
}
else{
Parray.push (item.content);
}
Parray.push ("</div></div></div>");
}
function initevents ()
{
Reset Scoller
Resetscoller ();
Scollerclick ();
Ulwrap.find ("Li:not (. X-tab-edge)"). each (function (e) {
Inititemevents (this);
});
}
function Inititemevents (Liitem)
{
Liswaphover.call (Liitem);
Liclick.call (Liitem);
Closeitemclick.call (Liitem);
}
function Scollerclick ()
{
if (Dfop.autoscroll)
{
Scrollerleft.click (function (e) {scolling ("left")});
Scrollerright.click (function (e) {scolling ("right")});
}
}
function Resetscoller ()
{
if (Dfop.autoscroll)
{
var edge = Ulwrap.find ("Li.x-tab-edge");
var eleft =edge.position (). Left;
var sleft = stripwrap.attr ("ScrollLeft");
if (sleft+eleft>innerwidth)
{
Header.addclass ("x-tab-scrolling");
Scrollerleft.css ("Visibility", "visible");
Scrollerright.css ("Visibility", "visible");
if (sleft>0)
{
Scrollerleft.removeclass ("x-tab-scroller-left-disabled");
}
else{
Scrollerleft.addclass ("x-tab-scroller-left-disabled");
}
if (eleft>innerwidth)
{
Scrollerright.removeclass ("x-tab-scroller-right-disabled");
}
else{
Scrollerright.addclass ("x-tab-scroller-right-disabled");
}
Dfop.showscrollnow =true;
}
Else
{
Header.removeclass ("x-tab-scrolling");
Stripwrap.animate ({"ScrollLeft": 0}, "fast");
Scrollerleft.css ("Visibility", "hidden");
Scrollerright.css ("Visibility", "hidden");
Dfop.showscrollnow =false;
}
}
}
//
function scolling (Type,max)
{
Debugger
if (!dfop.autoscroll | |!dfop.showscrollnow)
{
Return
}
Debugger
var swidth = stripwrap.attr ("ScrollWidth");
var sleft = stripwrap.attr ("ScrollLeft");
var edge = Ulwrap.find ("Li.x-tab-edge");
var eleft = Edge.position (). Left;
if (type== "left") {
if (Scrollerleft.hasclass ("x-tab-scroller-left-disabled"))
{
Return
}
if (sleft-dfop.scrollwidth-20>0)
{
Sleft-=dfop.scrollwidth;
}
else{
Sleft = 0;
Scrollerleft.addclass ("x-tab-scroller-left-disabled");
}
if (Scrollerright.hasclass ("x-tab-scroller-right-disabled"))
{
Scrollerright.removeclass ("x-tab-scroller-right-disabled");
}
Stripwrap.animate ({"ScrollLeft": Sleft}, "fast");
}
else{
if (Scrollerright.hasclass ("x-tab-scroller-right-disabled") &&!max)
{
Return
}
Left +;
if (max | | (Eleft>innerwidth && eleft-dfop.scrollwidth-20<=innerwidth))
{
Debugger
Sleft = sleft+eleft-(innerwidth-38);
Scrollerright.addclass ("x-tab-scroller-right-disabled");
Sleft = Eleft-innerwidth;
}
Else
{
Sleft +=dfop.scrollwidth;
}
if (sleft>0)
{
if (Scrollerleft.hasclass ("x-tab-scroller-left-disabled"))
{
Scrollerleft.removeclass ("x-tab-scroller-left-disabled");
}
}
Stripwrap.animate ({"ScrollLeft": Sleft}, "fast");
}
}
function Scollingtoli (Liitem)
{
var sleft = stripwrap.attr ("ScrollLeft");
var lleft = Liitem.position (). Left;
var lwidth = Liitem.outerwidth ();
var edge = Ulwrap.find ("Li.x-tab-edge");
var eleft = Edge.position (). Left;
if (lleft<=0)
{
Sleft + = (lleft-2);
if (sleft<0)
{
sleft=0;
Scrollerleft.addclass ("x-tab-scroller-left-disabled");
}
if (Scrollerright.hasclass ("x-tab-scroller-right-disabled"))
{
Scrollerright.removeclass ("x-tab-scroller-right-disabled");
}
Stripwrap.animate ({"ScrollLeft": Sleft}, "fast");
}
else{
if (lleft+lwidth>innerwidth-40)
{
Sleft = sleft+lleft+lwidth+-innerwidth+40; =scrollerleft and Scrollerrightwidth;
if (Scrollerleft.hasclass ("x-tab-scroller-left-disabled"))
{
Scrollerleft.removeclass ("x-tab-scroller-left-disabled");
}
Roll to the last one, then disable right;
if (eleft-(lleft+lwidth+-innerwidth+40) <=innerwidth)
{
Scrollerright.addclass ("x-tab-scroller-right-disabled");
}
Stripwrap.animate ({"ScrollLeft": Sleft}, "fast");
}
}
Liitem.click ();
}
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 = this.id.substr (7);
var Curr = Getactiveitem ();
if (curr!=null && itemid = = curr.id)
{
Return
}
var clickitem = GetItemByID (itemid);
if (Clickitem && clickitem.disabled)
{
return;
}
if (Curr)
{
$ ("#tab_li_" +curr.id). Removeclass ("x-tab-strip-active");
$ ("#tab_item_" +curr.id). AddClass ("X-hide-display");
Curr.isactive =false;
}
if (Clickitem)
{
$ (this). addclass ("x-tab-strip-active");
$ ("#tab_item_" +clickitem.id). Removeclass ("X-hide-display");
if (Clickitem.url)
{
var Cururl = $ ("#tab_item_frame_" +clickitem.id). attr ("src");
if (Cururl = = "About:blank")
{
$ ("#tab_item_frame_" +clickitem.id). attr ("src", clickitem.url);
}
}
else if (Clickitem.cuscall &&!clickitem.cuscalled)
{
var panel = $ ("#tab_item_content_" +clickitem.id);
var ret = Clickitem.cuscall (This,clickitem,panel);
Clickitem.cuscalled =true;
if (ret)//If a return value exists and is not NULL
{
Clickitem.content = ret;
Panel.html (ret);
}
}
Clickitem.isactive =true;
if (clickitem.onactive)
{
Clickitem.onactive.call (This,clickitem);
}
}
});
}
Get current Active item
function Getactiveitem ()
{
for (var i=0,j=dfop.items.length;i<j; i++)
{
if (dfop.items[i].isactive)
{
return dfop.items[i];
Break
}
}
return null;
}
Get item data based on ID
function GetItemByID (ID)
{
for (var i=0,j=dfop.items.length;i<j; i++)
{
if (dfop.items[i].id = = ID)
{
return dfop.items[i];
Break
}
}
return null;
}
function Getindexbyid (ID)
{
for (var i=0,j=dfop.items.length;i<j; i++)
{
if (dfop.items[i].id = = ID)
{
return i;
Break
}
}
return-1;
}
Add Item
function Addtabitem (item)
{
var chkitem =getitembyid (item.id);
if (!chkitem) {
var isactive =item.isactive;
Item.isactive =false;
var lastitem = dfop.items[dfop.items.length-1];
Dfop.items.push (item);
var Lastli = $ ("#tab_li_" +lastitem.id);
var Lastdiv = $ ("#tab_item_" +lastitem.id);
var litemp =[];
var bodytemp = [];
Builditemlihtml (item,litemp);
Builditembodyhtml (item,bodytemp);
var Liitem = $ (Litemp.join (""));
var bodyitem= $ (Bodytemp.join (""));
Lastli.after (Liitem);
Lastdiv.after (Bodyitem);
Event
var li = $ ("#tab_li_" +item.id);
Inititemevents (LI);
if (isactive)
{
Li.click ();
}
Resetscoller ();
Scolling ("Right", true);
}
else{
Alert ("The specified tab already exists!");
}
}
function Openitemoradd (item,allowadd)
{
var Checkitem = GetItemByID (item.id);
if (!checkitem && allowadd)
{
Addtabitem (item);
}
else{
var li = $ ("#tab_li_" +item.id);
Scollingtoli (LI);
}
}
Removing a tab item
function Deleteitembyliid (LIID)
{
var id= liid.substr (7);
$ ("#" +liid). Remove ();
$ ("#tab_item_" +id). Remove ();
var index = Getindexbyid (ID);
if (index>=0)
{
var nextcur;
if (Index < dfop.items.length-1)
{
Nextcur = dfop.items[index+1];
}
else if (index>0) {
Nextcur = Dfop.items[index-1];
}
if (nextcur)
{
$ ("#tab_li_" +nextcur.id). Click ();
}
Dfop.items.splice (index,1);
Resetscoller ();
Scolling ("Right", true);
}
}
function Resize (width,height)
{
if (width ==dfop.width && height ==dfop.height)
{
Return
}
if (width) {dfop.width=width};
if (height) {dfop.height =height;}
Innerwidth = width-2;
Bodyheight=dfop.height-headerheight;
Me.css ("width", dfop.width);
Header.css ("width", innerwidth);
Body.css ({width:innerwidth,height:bodyheight});
for (Var i=0,j=dfop.items.length;i<j;i++)
{
var item =dfop.items[i];
$ ("#tab_item_" +item.id). css ({width:innerwidth});
$ ("#tab_item_content_" +item.id). css ({width:innerwidth,height:bodyheight});
}
Resetscoller ();
}
Set whether a tab item is disabled
function Setdisabletabitem (itemid,disabled)
{
var chitem= getitembyid (itemId);
if (!chitem | | chitem.disabled ==disabled)
{
Return
}
if (disabled)
{
Chitem.disabled =true;
$ ("#tab_item_" +item.id). AddClass ("x-tab-strip-disabled");
}
else{
Chitem.disabled =false;
$ ("#tab_item_" +item.id). Removeclass ("x-tab-strip-disabled");
}
}
Me[0].tab = {
Addtabitem:addtabitem,
Opentabitem:openitemoradd,
Resize:resize,
Setdisabletabitem:setdisabletabitem
};
};
$.fn.addtabitem =function (item)
{
if (This[0].tab)
{
return This[0].tab.addtabitem (item);
}
return false;
}
$.fn.opentabitem =function (Item,oradd)
{
if (This[0].tab)
{
Return This[0].tab.opentabitem (Item,oradd);
}
return false;
}
$.fn.resizetabpanel =function (w,h)
{
if (This[0].tab)
{
Return This[0].tab.resize (W,H);
}
return false;
}
$.fn.setdisabletabitem =function (itemid,disabled)
{
if (This[0].tab)
{
Return This[0].tab.setdisabletabitem (itemid,disabled);
}
return false;
}
}) (JQuery);
Then let's take a step-by-step analysis of my implementation and start by writing the "template" for the jquery control, and refer to the explanation for why.
Copy Code code as follows:
; (function ($) {
$.fn.tabpanel =function (option) {
};
) (JQuery);
And then you write the default parameters
Copy Code code as follows:
var Dfop ={
Items:[],//Tab data item {id,text,classes,disabled,closeable,content,url,cuscall,onactive}
WIDTH:500,
height:400,
scrollwidth:100,//If there is a scroll bar, click the button every time the scroll distance
Automatically add scroll button when autoscroll:true//tab width is larger than container
};
The default parameters are relatively simple, I've added the annotation, which is the item array of items in trouble, but I believe that everyone by literal means already know most of it, I would like to describe it: ID is marked, must be unique, text display, classes specific style, such as the home page in the effect, I added an icon, it is implemented through this property, disabled is disabled, closeable can be closed,
Content and URL and cuscall three just set one of them, content is the actual contents of HTML, URL labeled content as a Web page, automatically add Iframe,cuscall to the content is a custom, This property is used to implement asynchronous content content, which is the result of cuscall execution.
Onactive is the event that is triggered when the tab item is activated. is a function to accept the item content, see Demo
The parameter is set up, and the default parameters are updated by the externally passed parameters:
$.extend (DFOP, option);
Then there is the part of building HTML, which is a bit longer and I don't repeat the code.
When we finish the HTML build, we will add the event to the HTML element, including the Click event of the tab, the left button, the right button click event, the mouse hover effect event of the tab, and so on.
Copy Code code as follows:
function initevents ()
{
Reset Scoller
Resetscoller (); Set whether the default appears to scroll off
Scollerclick (); The Click event of the scroll bar, if present
Ulwrap.find ("Li:not (. X-tab-edge)"). each (function (e) {
Inititemevents (this); Add events to each tab
});
}
function Inititemevents (Liitem)
{
Liswaphover.call (Liitem); The mouse hover effect on the tab
Liclick.call (Liitem); Click events for Tabs
Closeitemclick.call (Liitem); Click the Close button event
}
As for the realization of the event, in fact, to do it all, it is easy to take and conquer. The main cumbersome in the control of scrolling buttons and the appearance of the processing, and other click events are relatively simple.
The last is to expose the methods, and in order to expose these methods to write some internal methods, this tabpanel is naturally relatively simple and easy to use, while extensibility. We can make some adjustments according to the actual needs, of course, now the function should also meet most of the requirements.
Finally, let's take a look at the ways that are disclosed:
1: Dynamic new Tab method, that is, through JS dynamic new tab, here is the maintenance of the items data, and then call TabItem output HTML method, and finally set up the event alone. Simple
2: Checked or added. This is also through the JS call method, is the extension of the previous method, you can through JS to make a tab activation, if the item does not exist by the parameters to add this tab
3: Reset the size of the TabPanel, that is, to reset the size of the TabPanel through JS, this is called when the window size changes, very practical oh.
4: Set an item is disabled, through the JS method to set a TabItem state is disabled.
Finally, you can include the previous example of the control through the code, I have provided a compression package, but I also recommend practical SVN get the latest code. Because sometimes some small changes I do not inform the dispatch.
Http://code.google.com/p/xjplugin/downloads/list
Http://xiazai.jb51.net/201005/yuanma/xjPlugin_addtabpanel.rar