首页 > 代码库 > 我的开源框架之TAB控件

我的开源框架之TAB控件

需求

(1)支持iframe、html、json格式的tab内容远程请求

(2)支持动态添加tab

(3)支持远程加载完成监听,支持tab激活事件监听

(4)支持reload tab内容【如果是远程加载】

(5)支持邮件菜单【未实现】

实现图例

客户代码

 1 <body> 2     <div id="text"> 3         <h3>无题</h3> 4         <p>月落湖面两清影,</p> 5         <p>岸柳丝丝弄轻盈。</p>  6         <p>此番凉意写不出,</p>  7         <p>难画秋月一片晴。</p> </div> 8     <div style="padding-left:100px; padding-bottom:12px;"> 9         <div id="tabContainer" style="width:800px;height:260px">10             <div title="静态html"  closable="true" >项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1</div>11             <div title="iframe加载" isiframe="true" url="/innerpage.html" iconcls="icon-edit" closable="true">12             </div>13             <div title="远程HTML加载"  dataType="html" url="/content.html" iconcls="icon-save" closable="true">14             </div>15         </div>16     </div>17     <script type="text/javascript">       18         var tabs;19         $(function () {20             tabs = $("#tabContainer").tabs({21                 items: [{22                     title: ‘远程加载JSON数据‘,23                     closable: false,24                     iconcls: ‘icon-print‘,25                     actived: true,// 激活状态                   26                     url: ‘testServer/jsonQuestTest.ashx‘,//如果不配置采用公用 $.fn.tabs.defaults里的配置27                     dataType: ‘json‘// //如果不配置采用公用 $.fn.tabs.defaults里的配置 28                 },{29                     title: ‘文本测试‘,30                     closable: false,31                     iconcls: ‘icon-back‘,32                     actived: false,// 激活状态                   33                     content: $("#text") //‘<a>我是测试内容.....................</a>‘// 可以是文本,可以是$("#id")对象                    34                 }],35                 onl oadSuccess: function (title, context) {36                     console.log(title + "加载完成");                    37                     if (title == "远程加载JSON数据" || title == "动态添加tab") {38                        context.target.html(JSON.stringify(context.data));39                     }40                 },41                 activedHandler: function (tilte,context) {42                     console.log("actived=" + tilte);43                 },44                 closedHandler: function (title) {45                     console.log("closed=" + title);46                 }47             });48         });49         function addTab() {50             tabs.tabs("addTabs", {51                 title: ‘动态添加tab‘,52                 closable: true,53                 iconcls: ‘icon-back‘,54                 actived: false,// 激活状态                   55                 //content: ‘<a>我是动态tab内容</a>‘56                 url: ‘testServer/jsonQuestTest.ashx‘,//如果不配置采用公用 $.fn.tabs.defaults里的配置57                 dataType: ‘json‘,// //如果不配置采用公用 $.fn.tabs.defaults里的配置 58                 onl oadSuccess: function (title, context) {59                     context.target.html(title+"loadsucc;我自己注册的事件 "+JSON.stringify(context.data));60                 }61             });62         }63         function getSelectedTab() {64            var res =  tabs.tabs("getSelectedTab");65            alert(res.titleObj.attr("title"));66         }67         function reload() {68             var itemsopt = $("#itemsopt").children("option[selected]");69             tabs.tabs("reLoadTab", itemsopt.val());70             if (tabs.tabs("isExist", itemsopt.val())) {71                 console.log(itemsopt.val()+"exist");72             } else {73                 console.log(itemsopt.val() + "no exist");74             }75             76         }77     </script>78 </body>

组件代码

  1 /**************************************************************  2 *作者:hjwen  3 *电邮:hjwen88@126.com  4 *版本:1.0  5 *版权许可:中国通用开源许可协议V1.0  6 *说明:myui组件tabs组件  7 ***************************************************************/  8 (function ($) {  9     /****** 10     *渲染目标:renderHtml为构建html结构的函数,init初始化会调用 11     *******/ 12     var contentPadding = 6; 13     var showTitleItem = null; 14     var showContentItem = null; 15     var itemTitleContainer, itemContentContainer, existItems; 16     var headerWith = 0; 17     var itemsWidth = 0; 18     var leftMoreBtn = null, rightMoreBtn = null; 19     function renderHtml(target, opts) { 20         itemContentContainer = target; 21         var panel = target.panel({ expandable: false, maximizable: false, closeable: false, expanded: false }); 22         var titleWrap = target.prev("div"); 23         headerWith = titleWrap.width(); 24         var panelTitle = titleWrap.children(".panel-tilte"); 25         itemTitleContainer = $("<ul class=\"tabsul\"></ul>").appendTo(panelTitle); 26         target.css({ "overflow": "hidden", "padding": "0px" }); 27         existItems.css({ "width": target.width() - contentPadding * 2 + "px", "height": target.height() - contentPadding * 2 + "px", "margin": "0px", "padding": contentPadding + "px", "overflow": "auto" }).hide(); 28         createTabs(opts.items); 29         existItems = null; 30     }; 31     /**********私有方法开始********************/ 32     function createTabs(items) { 33         $.each(items, function (i, item) { 34             createTab(item, i); 35         }); 36         showContentItem.show(); 37         showTitleItem.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");         38     } 39     function createTab(item, index) { 40         //创建tab标题项 41         var a_tag = "<a href=‘javascript:void(0)‘>"; 42         if (item.iconcls != ‘‘) 43             a_tag = a_tag + "<span class=‘item_title_ioc " + item.iconcls + "‘></span>"; 44         if (item.closable) 45             a_tag = a_tag + "<span class=‘item_title_text‘>" + item.title + "</span><span  for=" + index + " class=‘item_title_close‘ ></span></a>"; 46         else 47             a_tag = a_tag + "<span class=‘item_title_text‘>" + item.title + "</span></a>"; 48         var itemTitleLi = $("<li contextmenu=\"" + item.contextMenu + "\" datatype=\"" + item.dataType + "\" url=\"" + item.url + "\" isiframe=\"" + item.isiframe + "\" title=\"" + item.title + "\" closable=\"" + item.closable + "\" actived=\"" + item.actived + "\" for=" + index + ">" + a_tag + "</li>").appendTo(itemTitleContainer); 49         itemTitleLi.bind({ 50             "click": function () { 51                 var $this = $(this); 52                 if ($this.attr("actived") == "true") 53                     return; 54                 var idx = $this.attr("for"); 55                 showContentItem.hide(); 56                 showTitleItem.attr("actived", "false").children("a").removeClass("tabs_selected").css("border-bottom", "1px solid #99BBE8"); 57                 $.each(itemContentContainer.children("div"), function (j, obj) { 58                     var $obj = $(obj); 59                     if (j == parseInt(idx)) { 60                         $this.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF"); 61                         showContentItem = $obj.show(); 62                         showTitleItem = $this; 63                     } 64                 }); 65                 if (item.activedHandler != null) { 66                     item.activedHandler(showTitleItem.attr("title"), { titleObj: showTitleItem, conetentObj: showContentItem }); 67                 } 68             }             69         }); 70         //如果可以关闭 71         if (item.closable) { 72             itemTitleLi.children("a").children(".item_title_close").bind({ 73                 click: function () { 74                     var allIts = itemContentContainer.children("div"); 75                     var $t = $(this); 76                     var foridx = parseInt($t.attr("for")); 77                     var removeContent = null; 78                     for (var k = 0, len = allIts.length; k < len; ++k) { 79                         if (foridx == k) { 80                             removeContent = $(allIts[k]); 81                             break; 82                         } 83                     }; 84                     //如果关闭的是激活的tab,则需要调整激活的tab 85                     var showIdx = 0; 86                     var titleLi = $t.parent("a").parent("li"); 87                     if (titleLi.attr("actived") == "true") { 88                         var showIt = titleLi.prev("li"); 89                         showIdx = foridx - 1; 90                         if (showIt.length == 0) { 91                             showIt = titleLi.next("li"); 92                             showIdx = foridx + 1; 93                         } 94                         showTitleItem = showIt; 95                         showTitleItem.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF"); 96                         //激活对应的内容div 97                         for (var k = 0, len = allIts.length; k < len; ++k) { 98                             if (showIdx == k) { 99                                 $(allIts[k]).show();100                                 break;101                             }102                         };103                     }104                     //修改删除项目后面所有li项的for属性105                     var nextAll = titleLi.nextAll();106                     if (nextAll.length > 0) {107                         setTimeout(function () {108                             $.each(nextAll, function (j, obj) {109                                 var $obj = $(obj);110                                 var curFor = parseInt($obj.attr("for"));111                                 var newFor = curFor - 1;112                                 $obj.attr("for", newFor);113                                 $obj.children("a").children(".item_title_close").attr("for", newFor);114                             });115                         }, 0);116                     }117                     var title = titleLi.attr("title");118                     itemsWidth = itemsWidth - titleLi.outerWidth()-11;119                     titleLi.remove();120                     removeContent.remove();121                     showMoreBtn();122                     if (item.closedHandler != null)123                         item.closedHandler(title);124                 },125                 mouseover: function () {126                     $(this).css("background-color", "#8DE2B3");127                 },128                 mouseout: function () {129                     $(this).attr("style", "");130                 }131             });132         }133         var contentDiv;134         if (item.exist) {//已经存在的不用再创建内容div135             contentDiv = $(existItems[index]);136         } else {137             contentDiv = $("<div></div>").appendTo(itemContentContainer).css({ "width": itemContentContainer.width() - contentPadding * 2 + "px", "height": itemContentContainer.height() - contentPadding * 2 + "px", "margin": "0px", "padding": contentPadding + "px", "overflow": "auto" }).hide();;138         }139         if (item.content != "") {//优先取content140             if ($.isPlainObject(item.content)) {141                 item.content.remove().appendTo(contentDiv);142             } else {143                 contentDiv.html(item.content);144             }145         } else {146             //是否有url 远程加载147             if (item.url != "") {148                 load(contentDiv, item,false);149             }150         }151         if (index == 0) {//默认第一个为激活状态152             showTitleItem = itemTitleLi;153             showContentItem = contentDiv;154         }155         if (item.actived) {156             showTitleItem = itemTitleLi;157             showContentItem = contentDiv;158         }159         itemsWidth = itemsWidth + itemTitleLi.outerWidth()+11;       160         showMoreBtn();161     };162     function load(target,item,isReload) {163         if (item.isiframe) {164             target.css({ "overflow": "hidden", "padding": "0", "width": target.width() + contentPadding * 2 + "px", "height": target.height() + contentPadding * 2 + "px" });165             var loading = $("<div class=‘loading icon-loading‘>正在加载......</div>").appendTo(target);166             var iframe;167             if (isReload) {168                 iframe = target.children("iframe")[0];169                 iframe.contentWindow.location.reload();170             } else {171                 iframe = $("<iframe title=‘" + item.title + "‘ frameborder=‘0‘ style=‘overflow:visible‘ scrolling=‘auto‘ width=‘100%‘ height=‘100%‘ src=http://www.mamicode.com/‘" + item.url + "‘ ></iframe>").appendTo(target);172                 iframe.load(function () {173                     loading.remove();174                     if (item.onLoadSuccess != null)175                         item.onLoadSuccess($(this).attr(‘title‘), target);176                 });177             }        178         } else {179             if (item.dataType == "json") {180                 var ajaxopt = {181                     url: item.url,182                     loadingContainer: target,183                     returnParams: true,184                     params: { title: encodeURIComponent(item.title) }185                 };186                 if (item.onLoadSuccess != null)187                     ajaxopt.okdeal = function (data, extParams) {188                         item.onLoadSuccess(decodeURIComponent(extParams.title), { data: data, target: target });189                     };190                 $.myui.ajaxRequest(ajaxopt);191             } else {192                 var settings = { url: item.url, extParam: item.title };193                 if (item.onLoadSuccess != null)194                     settings.loaded = function (t, extParam) {195                         item.onLoadSuccess(extParam, t);196                     };197                 $.myui.objectLoadContect({198                     target: target,199                     settings: settings200                 });201             }202         }203     };204     function showMoreBtn() {205         if (itemsWidth > headerWith) {206             itemTitleContainer.css("padding-left","9px");207             if (leftMoreBtn == null) {208                 var headerWrap = itemTitleContainer.parent("div").parent("div");209                 leftMoreBtn = $("<a class=‘leftMoreBtn‘></a>").appendTo(headerWrap);210                 rightMoreBtn = $("<a class=‘rightMoreBtn‘></a>").appendTo(headerWrap);211                 leftMoreBtn.bind(‘click‘, function () {212                     var position = itemTitleContainer.position();213                     if (position.left < 9) {214                         var pos = position.left +80;215                         itemTitleContainer.animate({ left: pos },500);216                     }217                 });218                 rightMoreBtn.bind(‘click‘, function () {219                     var position = itemTitleContainer.position();220                     var pos = position.left -80;                 221                     itemTitleContainer.animate({ left: pos},500);222                 });223             } else {224                 leftMoreBtn.show();225                 rightMoreBtn.show();226             }227             var diff = itemsWidth - headerWith;           228             itemTitleContainer.animate({ left: -diff }, 500);229         } else {            230             if (leftMoreBtn != null) {231                 itemTitleContainer.css("padding-left", "0px");232                 leftMoreBtn.hide();233                 rightMoreBtn.hide();234                 var position = itemTitleContainer.position();235                 if (position.left < 0) {236                     itemTitleContainer.animate({ left: 0 }, 500);237                 }238             }239         }240     }241     /**********私有方法结束*******************/242     /*****************************************************************************243     *对外的函数统一封装到methods中244     *调用方式:$.pluginInstance.pluginName("methodName",params) 245     ******************************************************************************/246     var methods = {247         init: function (options) {248             return this.each(function () {249                 var $this = $(this);250                 var settings251                 if (typeof options == ‘undefined‘)252                     settings = $.fn.tabs.defaults;253                 else254                     settings = $.extend({}, $.fn.tabs.defaults, options);255                 var newItemArr = [];256                 existItems = $this.children("div");//已经存在的item项257                 if (existItems.length > 0) {258                     $.each(existItems, function (i, it) {259                         var $it = $(it);260                         newItemArr.push({261                             title: $it.attr("title"),262                             content: ‘‘,263                             contextMenu: false,264                             closable: $it.attr("closable") == "true" ? true : false,265                             iconcls: $it.attr("iconcls") == undefined ? "" : $it.attr("iconcls"),266                             actived: $it.attr("actived") == "true" ? true : false,// 激活状态267                             isiframe: $it.attr("isiframe") == "true" ? true : false,//如果不配置采用公用 $.fn.tabs.defaults里的配置268                             url: $it.attr("url") == undefined ? "" : $it.attr("url"),//如果不配置采用公用 $.fn.tabs.defaults里的配置269                             dataType: $it.attr("dataType") == undefined ? "json" : $it.attr("dataType"),  //如果不配置采用公用 $.fn.tabs.defaults里的配置270                             exist: true, //271                             onl oadSuccess: settings.onLoadSuccess,//fn(tabtitle,resdata)272                             activedHandler: settings.activedHandler,//fn(tabtitle,context)273                             closedHandler: settings.closedHandler //fn(tabtitle) tab被关闭时触发274                         });275                     });276                 }277                 //合并每一个tab项的默认设置278                 $.each(settings.items, function (i, item) {279                     var newIt = $.extend({}, $.fn.tabs.itemdefaults, item);280                     newIt.exist = false;281                     if (typeof newIt.onLoadSuccess!=‘function‘)282                         newIt.onLoadSuccess = settings.onLoadSuccess;//fn(tabtitle,resdata)283                     if (typeof newIt.activedHandler != ‘function‘)284                         newIt.activedHandler = settings.activedHandler;//fn(tabtitle,context)285                     if (typeof newIt.closedHandler != ‘function‘)286                         newIt.closedHandler = settings.closedHandler; //fn(tabtitle) tab被关闭时触发287                     newItemArr.push(newIt);288                 });289                 settings.items = newItemArr;290                 //创建ui布局291                 renderHtml($this, settings);292                 if ($.myui.isDebug) {293                     $.myui.log("jQuery.tabs init finish......");294                 }295                 $this.data(‘settings‘, settings);296             });297         },298         destroy: function (options) {299             return $(this).each(function () {300                 var $this = $(this);301                 $this.removeData(‘settings‘);302             });303         },304         /***305         *opt={306             title: ‘tab标题‘,307             closable: false,308             iconcls: ‘‘,309             actived: false,// 激活状态310             isiframe: false,//如果不配置采用公用 $.fn.tabs.defaults里的配置311             url: ‘‘,//如果不配置采用公用 $.fn.tabs.defaults里的配置312             content: ‘‘,//内容默认为空,如果该属性有值,则优先默认采用这个,即使设置url也不会去远程加载数据,content可以是html对象,也可以是文本313             dataType: ‘json‘,// //如果不配置采用公用 $.fn.tabs.defaults里的配置314             contextMenu: false //右键菜单未实现315         }316         ***/317         addTabs: function (opts) {318             var newOpt = $.extend({}, $.fn.tabs.itemdefaults, opts);319             newOpt.actived = true;            320             return $(this).each(function () {321                 var $this = $(this);322                 var settings = $this.data(‘settings‘);323                 if (showContentItem != null)324                     showContentItem.hide();325                 if (showTitleItem != null)326                     showTitleItem.attr("actived", "false").children("a").removeClass("tabs_selected").css("border-bottom", "1px solid #99BBE8");327                 itemContentContainer = $this;328                 var index = $this.children("div").length;329                 if (typeof newOpt.onLoadSuccess != ‘function‘)330                     newOpt.onLoadSuccess = settings.onLoadSuccess;//fn(tabtitle,resdata)331                 if (typeof newOpt.activedHandler != ‘function‘)332                     newOpt.activedHandler = settings.activedHandler;//fn(tabtitle,context)333                 if (typeof newOpt.closedHandler != ‘function‘)334                     newOpt.closedHandler = settings.closedHandler; //fn(tabtitle) tab被关闭时触发335                 createTab(newOpt, index);336                 showContentItem.show();337                 showTitleItem.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");338             });339         },340         /**341         * 获取选中的tab,返回值{titleObj:...,contentObj:...}342         ***/343         getSelectedTab: function () {344             return { titleObj: showTitleItem, contentObj: showContentItem };345         },346         /***347         *重新加载某个tab,以title为标准348         ****/349         reLoadTab: function (title) {350             var $this = $(this);351             var titlelis = $this.prev().children(".panel-tilte").children("ul").children();352             var forIdx = -1;353             var url = ‘‘;354             var isIframe = false;355             var dataType = "html";356             var currShowTitle = null;357             for (var i = 0, len = titlelis.length; i < len; ++i) {358                 var $li = $(titlelis[i]);359                 if ($li.attr("title") == title && $li.attr("url") != undefined && $li.attr("url")!=‘‘) {360                     forIdx = i;361                     url = $li.attr("url");362                     if ($li.attr("isiframe") != undefined) {363                         isIframe = $li.attr("isiframe") == ‘true‘;364                     }365                     if ($li.attr("datatype") != undefined) {366                         dataType = $li.attr("datatype");367                     }368                     currShowTitle = $li;369                     break;370                 }371             }372             if (forIdx != -1) {373                 var childs = $this.children();374                 var updateContent = null;375                 for (var i = 0, len = childs.length; i < len;++i){376                     if (i == forIdx) {377                         updateContent = $(childs[i]);378                     }379                 }380                 if (updateContent != null) {381                     var opts = $this.data(‘settings‘);382                     var it;383                     for (var j = 0, len = opts.items.length; j < len;++j){384                         if (forIdx == j)385                             it = opts.items[j];386                     }387                     if (showTitleItem.attr("title") != title) {                     388                         showContentItem.hide();                    389                         showTitleItem.attr("actived", "false").children("a").removeClass("tabs_selected").css("border-bottom", "1px solid #99BBE8");390                         showContentItem= updateContent.show();391                         showTitleItem = currShowTitle.attr("actived", "true");392                         showTitleItem.children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");393                     }               394                     load(updateContent, it, true);395                 }396             }397             return $this;398         },399         /****400         * 判断某个tab是否存在401         ****/402         isExist: function (title) {403             var $this = $(this);404             var titlelis = $this.prev().children(".panel-tilte").children("ul").children();405             var forIdx = -1;          406             for (var i = 0, len = titlelis.length; i < len; ++i) {407                 var $li = $(titlelis[i]);408                 if ($li.attr("title") == title && $li.attr("url") != undefined && $li.attr("url") != ‘‘) {409                     forIdx = i; 410                     break;411                 }412             }413             if (forIdx > -1)414                 return true;415             else416                 return false;417         }        418     };419     /********************420     *组件的构造函数421     *********************/422     $.fn.tabs = function () {423         var method = arguments[0];424         if (methods[method]) {425             method = methods[method];426             arguments = Array.prototype.slice.call(arguments, 1);427         } else if (typeof (method) == ‘object‘ || !method) {428             if ($.myui.isDebug) {429                 $.myui.log("jQuery.tabs init.....");430             }431             method = methods.init;432         } else {433             $.error(‘Method ‘ + method + ‘ does not exist on jQuery.tabs‘);434             return this;435         }436         return method.apply(this, arguments);437     };438     /********************439     *组件的默认配置值440     *options={441         items: [], //tab项配置,对应$.fn.tabs.itemdefaults442         isiframe: false,// 是否嵌入iframe,嵌入iframe 需要与url配合使用,即采用url加载远程页面时【dataType=html】才起作用443         url: ‘‘,444         dataType: ‘json‘,// json/html 远程加载时的数据格式445         onl oadSuccess: null,//fn(tabtitle,resdata)446         activedHandler: null,//fn(tabtitle,context)447         closedHandler: null //fn(tabtitle) tab被关闭时触发448     }449     *********************/450     $.fn.tabs.defaults = {451         items: [], //tab项配置,对应$.fn.tabs.itemdefaults452         isiframe: false,// 是否嵌入iframe,嵌入iframe 需要与url配合使用,即采用url加载远程页面时【dataType=html】才起作用453         url: ‘‘,454         dataType: ‘json‘,// json/html 远程加载时的数据格式455         onl oadSuccess: null,//fn(tabtitle,resdata)456         activedHandler: null,//fn(tabtitle)457         closedHandler: null //fn(tabtitle) tab被关闭时触发458     };459     /***460     *每一个tab项目的默认配置461     ****/462     $.fn.tabs.itemdefaults = {463         title: ‘tab标题‘,464         closable: false,465         iconcls: ‘‘,466         actived: false,// 激活状态467         isiframe: false,//如果不配置采用公用 $.fn.tabs.defaults里的配置468         url: ‘‘,//如果不配置采用公用 $.fn.tabs.defaults里的配置469         content: ‘‘,//内容默认为空,如果该属性有值,则优先默认采用这个,即使设置url也不会去远程加载数据,content可以是html对象,也可以是文本470         dataType: ‘json‘,// //如果不配置采用公用 $.fn.tabs.defaults里的配置 471         contextMenu: false //右键菜单未实现472     }473 })(jQuery);