zoukankan      html  css  js  c++  java
  • easyui tabs源码阅读(未完待续)

      1 /**
      2  * jQuery EasyUI 1.2.5
      3  * 
      4  * Licensed under the GPL terms
      5  * To use it on other terms please contact us
      6  *
      7  * Copyright(c) 2009-2011 stworthy [ stworthy@gmail.com ] 
      8  * 
      9  */
     10 (function($) {
     11     function getMaxScrollWidth(jq) {
     12         var header = $(jq).children("div.tabs-header");
     13         var tabsWidth = 0;
     14         $("ul.tabs li", header).each(function() {
     15             tabsWidth += $(this).outerWidth(true);
     16         });
     17         var wrapWidth = header.children("div.tabs-wrap").width();
     18         var padding = parseInt(header.find("ul.tabs").css("padding-left"));
     19         return tabsWidth - wrapWidth + padding;
     20     };
     21     function setScrollers(jq) {
     22         var opts = $.data(jq, "tabs").options;
     23         var header = $(jq).children("div.tabs-header");
     24         var tool = header.children("div.tabs-tool");
     25         var leftScroller = header.children("div.tabs-scroller-left");
     26         var rightScroller = header.children("div.tabs-scroller-right");
     27         var wrap = header.children("div.tabs-wrap");
     28         var height = ($.boxModel == true ? (header.outerHeight() - (tool.outerHeight() - tool
     29                 .height()))
     30                 : header.outerHeight());
     31         if (opts.plain) {
     32             height -= 2;
     33         }
     34         tool.height(height);
     35         var fullWidth = 0;
     36         $("ul.tabs li", header).each(function() {
     37             fullWidth += $(this).outerWidth(true);
     38         });
     39         var realWidth = header.width() - tool.outerWidth();
     40         if (fullWidth > realWidth) {
     41             leftScroller.show();
     42             rightScroller.show();
     43             tool.css("right", rightScroller.outerWidth());
     44             wrap.css( {
     45                 marginLeft : leftScroller.outerWidth(),
     46                 marginRight : rightScroller.outerWidth() + tool.outerWidth(),
     47                 left : 0,
     48                 width : realWidth - leftScroller.outerWidth() - rightScroller.outerWidth()
     49             });
     50         } else {
     51             leftScroller.hide();
     52             rightScroller.hide();
     53             tool.css("right", 0);
     54             wrap.css( {
     55                 marginLeft : 0,
     56                 marginRight : tool.outerWidth(),
     57                 left : 0,
     58                 width : realWidth
     59             });
     60             wrap.scrollLeft(0);
     61         }
     62     };
     63     function buildButton(jq) {
     64         var opts = $.data(jq, "tabs").options;
     65         var header = $(jq).children("div.tabs-header");
     66         if (opts.tools) {
     67             if (typeof opts.tools == "string") {
     68                 $(opts.tools).addClass("tabs-tool").appendTo(header);
     69                 $(opts.tools).show();
     70             } else {
     71                 header.children("div.tabs-tool").remove();
     72                 var tool = $("<div class=\"tabs-tool\"></div>").appendTo(header);
     73                 for ( var i = 0; i < opts.tools.length; i++) {
     74                     var button = $("<a href=\"javascript:void(0);\"></a>")
     75                             .appendTo(tool);
     76                     button[0].onclick = eval(opts.tools[i].handler || function() {
     77                     });
     78                     button.linkbutton($.extend( {}, opts.tools[i], {
     79                         plain : true
     80                     }));
     81                 }
     82             }
     83         } else {
     84             header.children("div.tabs-tool").remove();
     85         }
     86     };
     87     
     88     /**
     89     *设置tabs的尺寸,其中还判断了盒模式,以适用各种浏览器
     90     */
     91     function setSize(jq) {
     92         var opts = $.data(jq, "tabs").options;
     93         var cc = $(jq);
     94         if (opts.fit == true) {
     95             var p = cc.parent();
     96             opts.width = p.width();
     97             opts.height = p.height();
     98         }
     99         cc.width(opts.width).height(opts.height);
    100         var header = $(jq).children("div.tabs-header");
    101         if ($.boxModel == true) {
    102             header.width(opts.width - (header.outerWidth() - header.width()));
    103         } else {
    104             header.width(opts.width);
    105         }
    106         setScrollers(jq);
    107         var panels = $(jq).children("div.tabs-panels");
    108         var height = opts.height;
    109         if (!isNaN(height)) {
    110             if ($.boxModel == true) {
    111                 var height = panels.outerHeight() - panels.height();
    112                 panels.css("height", (height - header.outerHeight() - height) || "auto");
    113             } else {
    114                 panels.css("height", height - header.outerHeight());
    115             }
    116         } else {
    117             panels.height("auto");
    118         }
    119         var width = opts.width;
    120         if (!isNaN(width)) {
    121             if ($.boxModel == true) {
    122                 panels.width(width - (panels.outerWidth() - panels.width()));
    123             } else {
    124                 panels.width(width);
    125             }
    126         } else {
    127             panels.width("auto");
    128         }
    129     };
    130     
    131     function fitContent(jq) {
    132         var opts = $.data(jq, "tabs").options;
    133         var tab = getSelected(jq);
    134         if (tab) {
    135             var panels = $(jq).children("div.tabs-panels");
    136             var width = opts.width == "auto" ? "auto" : panels.width();
    137             var height = opts.height == "auto" ? "auto" : panels.height();
    138             tab.panel("resize", {
    139                 width : width,
    140                 height : height
    141             });
    142         }
    143     };
    144     
    145     /**
    146     *此处的jq指class为"easyui-tabs"的div
    147     */
    148     function wrapTabs(jq) {
    149         var cc = $(jq);
    150         cc.addClass("tabs-container");
    151         //将class为"easyui-tabs"的div的子内容用"<div class=\"tabs-panels\"/>"包裹起来;
    152         cc.wrapInner("<div class=\"tabs-panels\"/>");
    153         
    154         //在class为"tabs-header"的div前添加div
    155         $("<div class=\"tabs-header\">"
    156                 + "<div class=\"tabs-scroller-left\"></div>"
    157                 + "<div class=\"tabs-scroller-right\"></div>"
    158                 + "<div class=\"tabs-wrap\">"
    159                 + "<ul class=\"tabs\"></ul>" + "</div>" + "</div>")
    160                 .prependTo(jq);
    161         var tabs = [];
    162         var tp = cc.children("div.tabs-panels");
    163         tp.children("div[selected]").attr("toselect", "true");
    164         //根据最初class为"easyui-tabs"的div的子div创建tabs
    165         tp.children("div").each(function() {
    166             var pp = $(this);
    167             tabs.push(pp);
    168             createTab(jq, pp);
    169         });
    170         cc.children("div.tabs-header").find(
    171                 ".tabs-scroller-left, .tabs-scroller-right").hover(function() {
    172             $(this).addClass("tabs-scroller-over");
    173         }, function() {
    174             $(this).removeClass("tabs-scroller-over");
    175         });
    176         cc.bind("_resize", function(e, param) {
    177             var opts = $.data(jq, "tabs").options;
    178             if (opts.fit == true || param) {
    179                 setSize(jq);
    180                 fitContent(jq);
    181             }
    182             return false;
    183         });
    184         return tabs;
    185     };
    186     function setProperties(jq) {
    187         var opts = $.data(jq, "tabs").options;
    188         var header = $(jq).children("div.tabs-header");//获取class为tabs-header的div,此div即为tabs标签部分;
    189         var panel = $(jq).children("div.tabs-panels");//获取class为tabs-panels的div,此div即为tabs中要展示的内容;
    190         //如果属性plain为true,则设置tabs标签的背景为透明(默认为true);
    191         if (opts.plain == true) {
    192             header.addClass("tabs-header-plain");
    193         } else {
    194             header.removeClass("tabs-header-plain");
    195         }
    196         if (opts.border == true) {
    197             header.removeClass("tabs-header-noborder");
    198             panel.removeClass("tabs-panels-noborder");
    199         } else {
    200             header.addClass("tabs-header-noborder");
    201             panel.addClass("tabs-panels-noborder");
    202         }
    203         //给header的子孙元素中class为".tabs-scroller-left"的div绑定一个自定义事件"click.tabs";
    204         $(".tabs-scroller-left", header).unbind(".tabs").bind("click.tabs",
    205                 function() {
    206                     var header = $(".tabs-wrap", header);
    207                     //scrollLeft 获取匹配元素相对滚动条左侧的偏移;
    208                     var pos = header.scrollLeft() - opts.scrollIncrement;
    209                     header.animate( {
    210                         scrollLeft : pos
    211                     }, opts.scrollDuration);
    212                 });
    213         $(".tabs-scroller-right", header).unbind(".tabs").bind(
    214                 "click.tabs",
    215                 function() {
    216                     var header = $(".tabs-wrap", header);
    217                     var pos = Math.min(header.scrollLeft() + opts.scrollIncrement,
    218                             getMaxScrollWidth(jq));
    219                     header.animate( {
    220                         scrollLeft : pos
    221                     }, opts.scrollDuration);
    222                 });
    223         var tabs = $.data(jq, "tabs").tabs;
    224         for ( var i = 0, len = tabs.length; i < len; i++) {
    225             var tab = tabs[i];
    226             var tab = tab.panel("options").tab;
    227             tab.unbind(".tabs").bind("click.tabs", {
    228                 p : tab
    229             }, function(e) {
    230                 selectTab(jq, getTabIndex(jq, e.data.p));
    231             }).bind("contextmenu.tabs",{
    232                         p : tab
    233                     },
    234                     function(e) {
    235                         opts.onContextMenu.call(jq, e, e.data.p.panel("options").title);
    236                     });
    237             tab.find("a.tabs-close").unbind(".tabs").bind("click.tabs", {
    238                 p : tab
    239             }, function(e) {
    240                 closeTab(jq, getTabIndex(jq, e.data.p));
    241                 return false;
    242             });
    243         }
    244     };
    245     function createTab(container, pp, options) {
    246         options = options || {};
    247         pp.panel($.extend( {}, options, {
    248             border : false,
    249             noheader : true,
    250             closed : true,
    251             doSize : false,
    252             iconCls : (options.icon ? options.icon : undefined),
    253             onLoad : function() {
    254                 if (options.onLoad) {
    255                     options.onLoad.call(this, arguments);
    256                 }
    257                 $.data(container, "tabs").options.onLoad.call(container, pp);
    258             }
    259         }));
    260         var opts = pp.panel("options");
    261         var header = $(container).children("div.tabs-header");
    262         var tabs = $("ul.tabs", header);
    263         var tab = $("<li></li>").appendTo(tabs);
    264         var tabInner = $("<a href=\"javascript:void(0)\" class=\"tabs-inner\"></a>")
    265                 .appendTo(tab);
    266         var tabTitle = $("<span class=\"tabs-title\"></span>").html(opts.title)
    267                 .appendTo(tabInner);
    268         var tabIcon = $("<span class=\"tabs-icon\"></span>").appendTo(tabInner);
    269         if (opts.closable) {
    270             tabTitle.addClass("tabs-closable");
    271             $("<a href=\"javascript:void(0)\" class=\"tabs-close\"></a>")
    272                     .appendTo(tab);
    273         }
    274         if (opts.iconCls) {
    275             tabTitle.addClass("tabs-with-icon");
    276             tabIcon.addClass(opts.iconCls);
    277         }
    278         if (opts.tools) {
    279             var tool = $("<span class=\"tabs-p-tool\"></span>").insertAfter(tabInner);
    280             if (typeof opts.tools == "string") {
    281                 $(opts.tools).children().appendTo(tool);
    282             } else {
    283                 for ( var i = 0; i < opts.tools.length; i++) {
    284                     var t = $("<a href=\"javascript:void(0)\"></a>").appendTo(tool);
    285                     t.addClass(opts.tools[i].iconCls);
    286                     if (opts.tools[i].handler) {
    287                         t.bind("click", eval(opts.tools[i].handler));
    288                     }
    289                 }
    290             }
    291             var pr = tool.children().length * 12;
    292             if (opts.closable) {
    293                 pr += 8;
    294             } else {
    295                 pr -= 3;
    296                 tool.css("right", "5px");
    297             }
    298             tabTitle.css("padding-right", pr + "px");
    299         }
    300         opts.tab = tab;
    301     };
    302     function addTab(jq, options) {
    303         var opts = $.data(jq, "tabs").options;
    304         var tabs = $.data(jq, "tabs").tabs;
    305         var pp = $("<div></div>").appendTo($(jq).children("div.tabs-panels"));
    306         tabs.push(pp);
    307         createTab(jq, pp, options);
    308         opts.onAdd.call(jq, options.title);
    309         setScrollers(jq);
    310         setProperties(jq);
    311         selectTab(jq, tabs.length - 1);
    312     };
    313     function update(jq, param) {
    314         var selectHis = $.data(jq, "tabs").selectHis;
    315         var pp = param.tab;
    316         var title = pp.panel("options").title;
    317         pp.panel($.extend( {}, param.options, {
    318             iconCls : (param.options.icon ? param.options.icon : undefined)
    319         }));
    320         var opts = pp.panel("options");
    321         var tab = opts.tab;
    322         tab.find("span.tabs-icon").attr("class", "tabs-icon");
    323         tab.find("a.tabs-close").remove();
    324         tab.find("span.tabs-title").html(opts.title);
    325         if (opts.closable) {
    326             tab.find("span.tabs-title").addClass("tabs-closable");
    327             $("<a href=\"javascript:void(0)\" class=\"tabs-close\"></a>").appendTo(tab);
    328         } else {
    329             tab.find("span.tabs-title").removeClass("tabs-closable");
    330         }
    331         if (opts.iconCls) {
    332             tab.find("span.tabs-title").addClass("tabs-with-icon");
    333             tab.find("span.tabs-icon").addClass(opts.iconCls);
    334         } else {
    335             tab.find("span.tabs-title").removeClass("tabs-with-icon");
    336         }
    337         if (title != opts.title) {
    338             for ( var i = 0; i < selectHis.length; i++) {
    339                 if (selectHis[i] == title) {
    340                     selectHis[i] = opts.title;
    341                 }
    342             }
    343         }
    344         setProperties(jq);
    345         $.data(jq, "tabs").options.onUpdate.call(jq, opts.title);
    346     };
    347     function closeTab(container, title) {
    348         var opts = $.data(container, "tabs").options;
    349         var tabs = $.data(container, "tabs").tabs;
    350         var selectHis = $.data(container, "tabs").selectHis;
    351         if (!exists(container, title)) {
    352             return;
    353         }
    354         var tab = getTab(container, title);
    355         var title = tab.panel("options").title;
    356         if (opts.onBeforeClose.call(container, title) == false) {
    357             return;
    358         }
    359         var tab = getTab(container, title, true);
    360         tab.panel("options").tab.remove();
    361         tab.panel("destroy");
    362         opts.onClose.call(container, title);
    363         setScrollers(container);
    364         for ( var i = 0; i < selectHis.length; i++) {
    365             if (selectHis[i] == title) {
    366                 selectHis.splice(i, 1);
    367                 i--;
    368             }
    369         }
    370         var lastTab = selectHis.pop();
    371         if (lastTab) {
    372             selectTab(container, lastTab);
    373         } else {
    374             if (tabs.length) {
    375                 selectTab(container, 0);
    376             }
    377         }
    378     };
    379     function getTab(container, title, close) {
    380         var tabs = $.data(container, "tabs").tabs;
    381         if (typeof title == "number") {
    382             if (title < 0 || title >= tabs.length) {
    383                 return null;
    384             } else {
    385                 var tab = tabs[title];
    386                 if (close) {
    387                     tabs.splice(title, 1);
    388                 }
    389                 return tab;
    390             }
    391         }
    392         for ( var i = 0; i < tabs.length; i++) {
    393             var tab = tabs[i];
    394             if (tab.panel("options").title == title) {
    395                 if (close) {
    396                     tabs.splice(i, 1);
    397                 }
    398                 return tab;
    399             }
    400         }
    401         return null;
    402     };
    403     function getTabIndex(jq, tab) {
    404         var tabs = $.data(jq, "tabs").tabs;
    405         for ( var i = 0; i < tabs.length; i++) {
    406             if (tabs[i][0] == $(tab)[0]) {
    407                 return i;
    408             }
    409         }
    410         return -1;
    411     };
    412     function getSelected(jq) {
    413         var tabs = $.data(jq, "tabs").tabs;
    414         for ( var i = 0; i < tabs.length; i++) {
    415             var tab = tabs[i];
    416             if (tab.panel("options").closed == false) {
    417                 return tab;
    418             }
    419         }
    420         return null;
    421     };
    422     function initSelectTab(jq) {
    423         var tabs = $.data(jq, "tabs").tabs;
    424         for ( var i = 0; i < tabs.length; i++) {
    425             if (tabs[i].attr("toselect") == "true") {
    426                 selectTab(jq, i);
    427                 return;
    428             }
    429         }
    430         if (tabs.length) {
    431             selectTab(jq, 0);
    432         }
    433     };
    434     function selectTab(jq, title) {
    435         var opts = $.data(jq, "tabs").options;
    436         var tabs = $.data(jq, "tabs").tabs;
    437         var selectHis = $.data(jq, "tabs").selectHis;
    438         if (tabs.length == 0) {
    439             return;
    440         }
    441         var tab = getTab(jq, title);
    442         if (!tab) {
    443             return;
    444         }
    445         var selected = getSelected(jq);
    446         if (selected) {
    447             selected.panel("close");
    448             selected.panel("options").tab.removeClass("tabs-selected");
    449         }
    450         tab.panel("open");
    451         var title = tab.panel("options").title;
    452         selectHis.push(title);
    453         var tab = tab.panel("options").tab;
    454         tab.addClass("tabs-selected");
    455         var wrap = $(jq).find(">div.tabs-header div.tabs-wrap");
    456         var leftPos = tab.position().left + wrap.scrollLeft();
    457         var left = leftPos - wrap.scrollLeft();
    458         var right = left + tab.outerWidth();
    459         if (left < 0 || right > wrap.innerWidth()) {
    460             var pos = Math.min(leftPos - (wrap.width() - tab.width()) / 2, getMaxScrollWidth(jq));
    461             wrap.animate( {
    462                 scrollLeft : pos
    463             }, opts.scrollDuration);
    464         } else {
    465             var pos = Math.min(wrap.scrollLeft(), getMaxScrollWidth(jq));
    466             wrap.animate( {
    467                 scrollLeft : pos
    468             }, opts.scrollDuration);
    469         }
    470         fitContent(jq);
    471         opts.onSelect.call(jq, title);
    472     };
    473     function exists(container, title) {
    474         return getTab(container, title) != null;
    475     };
    476     
    477     //构造函数
    478     $.fn.tabs = function(options, param) 
    479         //如果options为string类型,表明是调用tabs的方法;
    480         if (typeof options == "string") {
    481             return $.fn.tabs.methods[options](this, param);
    482         }
    483         options = options || {};
    484         return this.each(function() {
    485             var state = $.data(this, "tabs");
    486             var opts;
    487             if (state) {
    488                 opts = $.extend(state.options, options);
    489                 state.options = opts;
    490             } else {
    491                 $.data(this, "tabs", {
    492                     options : $.extend( {}, $.fn.tabs.defaults, $.fn.tabs
    493                             .parseOptions(this), options),
    494                     tabs : wrapTabs(this),
    495                     selectHis : []
    496                 });
    497             }
    498             buildButton(this);
    499             setProperties(this);
    500             setSize(this);
    501             initSelectTab(this);
    502         });
    503     };
    504     $.fn.tabs.methods = {
    505         options : function(jq) {
    506             return $.data(jq[0], "tabs").options;
    507         },
    508         tabs : function(jq) {
    509             return $.data(jq[0], "tabs").tabs;
    510         },
    511         resize : function(jq) {
    512             return jq.each(function() {
    513                 setSize(this);
    514                 fitContent(this);
    515             });
    516         },
    517         add : function(jq, options) {
    518             return jq.each(function() {
    519                 addTab(this, options);
    520             });
    521         },
    522         close : function(jq, title) {
    523             return jq.each(function() {
    524                 closeTab(this, title);
    525             });
    526         },
    527         getTab : function(jq, title) {
    528             return getTab(jq[0], title);
    529         },
    530         getTabIndex : function(jq, tab) {
    531             return getTabIndex(jq[0], tab);
    532         },
    533         getSelected : function(jq) {
    534             return getSelected(jq[0]);
    535         },
    536         select : function(jq, title) {
    537             return jq.each(function() {
    538                 selectTab(this, title);
    539             });
    540         },
    541         exists : function(jq, title) {
    542             return exists(jq[0], title);
    543         },
    544         update : function(jq, param) {
    545             return jq.each(function() {
    546                 update(this, param);
    547             });
    548         }
    549     };
    550     $.fn.tabs.parseOptions = function(target) {
    551         var t = $(target);
    552         return {
    553             width : (parseInt(target.style.width) || undefined),
    554             height : (parseInt(target.style.height) || undefined),
    555             fit : (t.attr("fit") ? t.attr("fit") == "true" : undefined),
    556             border : (t.attr("border") ? t.attr("border") == "true" : undefined),
    557             plain : (t.attr("plain") ? t.attr("plain") == "true" : undefined),
    558             tools : t.attr("tools")
    559         };
    560     };
    561     $.fn.tabs.defaults = {
    562         width : "auto",
    563         height : "auto",
    564         plain : false,
    565         fit : false,
    566         border : true,
    567         tools : null,
    568         scrollIncrement : 100,
    569         scrollDuration : 400,
    570         onLoad : function(panel) {
    571         },
    572         onSelect : function(title) {
    573         },
    574         onBeforeClose : function(title) {
    575         },
    576         onClose : function(title) {
    577         },
    578         onAdd : function(title) {
    579         },
    580         onUpdate : function(title) {
    581         },
    582         onContextMenu : function(e, title) {
    583         }
    584     };
    585 })(jQuery);
  • 相关阅读:
    VC2013一些感受
    第三周 分析程序题
    进度条——持续更新
    怪自己,不怪书
    源程序版本管理软件和项目管理软件
    学习进度条
    个人最终总结
    win8以上windows系统eclipse环境下图片显示乱码问题解决
    黄金点游戏
    编码用命令行执行的C语言词语统计程序
  • 原文地址:https://www.cnblogs.com/peislin/p/2914067.html
Copyright © 2011-2022 走看看