• 2012.05.21 jq Tab


    昨天星期天,玩了一天,晚上看了需求文档,所以没有花时间学习。

    今天继续实现jq tab。

    根据之前的进度,剩余的工作量包括:

    1.提供callback函数接口(完成)

    2.样式(实在非我所长。这个带回公司再用公司的样式加以调整)

    3.调整应该显示的tabs,数量不超过size(实现了添加设置按钮,还剩下添加加减符号,并实现从默认显示的tab和更多tab之间添加移除tab,相当于已实现三分之一)

    4.每个tab可以接受任意数据格式(未实现,这个想过,难度应该不大。)

    这里的callback函数接口,也是记录在config中,在初始化时传入。在创建ul时,会判断callback函数是否被正确传入,是的话,用callback.call(this, li.value)实现。

    暂时callback函数只能接受li的value属性。 当功能修改成可以接受任意数据格式后,这个callback函数会接受li对应的json对象。

    贴上代码和css,方便回公司修改:

    js:

    View Code
      1 /**
      2  * @author Steven
      3  */
      4 
      5 /*-------------- Common Functions ------------------*/
      6 function stopPropagation(e) {
      7     e = e || window.event;
      8     if(e.stopPropagation) { //W3C阻止冒泡方法
      9         e.stopPropagation();
     10     } else {
     11         e.cancelBubble = true; //IE阻止冒泡方法
     12     }
     13 }
     14 
     15 
     16 /*--------------------------------------------------*/
     17 var jqTabMaster = function(){
     18 };
     19 jqTabMaster.prototype.config = {
     20     containerID:"",
     21     size:0,
     22     realSize:0,
     23     items:[],
     24     showItems:[],
     25     "",
     26     callback:null
     27 };
     28 
     29 jqTabMaster.prototype.buildUl = function(startIndex, endIndex, className){
     30     var me = jqTabMaster.prototype,
     31         config = me.config,
     32         items = config.items,
     33         callback = config.callback,
     34         max = items.length-1,
     35         startIndex = (typeof startindex =='undefined' || isNaN(startIndex))? 0:startIndex,
     36         endIndex = (typeof endIndex =='undefined' || isNaN(endIndex))? max:endIndex,
     37         ul = document.createElement("ul"),
     38         li;
     39         
     40     for(var i =startIndex;i<=endIndex;i++){
     41         li = document.createElement("li");
     42         li.innerHTML = items[i].text;
     43         li.value = items[i].value;
     44         ul.appendChild(li);
     45     }
     46     if(!!className){
     47         ul.className = className;
     48     }
     49 
     50     me.bindTabsClickEvent(ul,callback);
     51     return ul;
     52 }
     53 
     54 jqTabMaster.prototype.bindTabsClickEvent = function(ul,callback){
     55     if(!!ul && ul.tagName=="UL" && typeof callback =="function"){
     56         ul.onclick = function(ev){
     57             var ev = ev || window.event,
     58                 target = ev.target || ev.srcElement;
     59             if(target.tagName == "LI"){
     60                 callback.call(this, target.value);
     61             }
     62             else
     63             {
     64                 return false;
     65             }                
     66         }
     67     }    
     68 }
     69 jqTabMaster.prototype.unbindTabsClickEvent = function(ul){
     70     if(!!ul && ul.tagName=="UL" && typeof callback =="function"){
     71         ul.onclick = null;
     72     }    
     73 }
     74 
     75 jqTabMaster.prototype.initial = function(option){
     76     this.config.containerID = option.containerID;
     77     this.config.size = option.size;
     78     this.config.items = option.items;
     79     this.config.width = option.width;    
     80     this.config.callback = option.callback;
     81 
     82     var me = jqTabMaster.prototype,
     83         container = $("#"+this.config.containerID),
     84         iLen,
     85         ul, 
     86         showItems = [],
     87         moreItemsCount = 0;
     88 
     89     container.hide();
     90     container.addClass('container');
     91     container.css('width',this.config.width);
     92     container.css('overflow','hidden');
     93     /*增加”更多“按钮,默认为disabled*/
     94     container.css({'width':'-=40px'});
     95     var moreBtn = $("<div id='divMoreBtn' class='no-more'><span>更多</span></div>");
     96     moreBtn.insertAfter(container);
     97  
     98      /* 添加可显示的tabs */
     99      iLen = Math.min(this.config.items.length,this.config.size);
    100      ul = jqTabMaster.prototype.buildUl(0, iLen);
    101     container.append(ul);    
    102     
    103     container.show();
    104     /* Get Real Size 
    105          由于这里要调用offsetTop来判断是否超出边界,调用offset的参数会比较耗性能,
    106          现在是用从头开始便利数组获取的,之后可以使用二分法来进行快速查找,以提高性能。
    107      * */
    108     var displayInfo = me.getRealDisplayInfo();
    109     this.config.realSize = displayInfo.realSize;
    110     this.config.showItems = displayInfo.showItems;
    111     
    112     /* 当tab没有完全显示时 */    
    113     if((this.config.items.length - this.config.realSize)>0){
    114         $("#divMoreBtn").toggleClass('no-more');
    115         /*绑定显示更多tab事件*/
    116         $("#divMoreBtn").bind('click',function(ev){
    117             me.showMoreTabs(ev);
    118         });
    119     }
    120 }
    121 
    122 jqTabMaster.prototype.getRealDisplayInfo = function(){
    123     var me = jqTabMaster.prototype,
    124         config = me.config,
    125         realSize = 0,
    126         lis = $("#"+config.containerID+" ul li"),
    127         showItems = [],
    128         originOffsetTop=null;
    129     
    130     lis.each(function(i){
    131         if(originOffsetTop==null){
    132             originOffsetTop = this.offsetTop;
    133             showItems.push(i);
    134         } else if( this.offsetTop!=originOffsetTop){
    135             return false;
    136         }
    137         realSize++;
    138     });
    139     return {realSize:realSize,showItems:showItems};
    140 }
    141 
    142 /*
    143  * params:
    144  * ev: window.event
    145  * me: jqTabMaster.prototype
    146  */
    147 jqTabMaster.prototype.showMoreTabs = function(ev){
    148     var me = jqTabMaster.prototype,
    149         config = me.config,
    150         ev = ev || window.event,
    151         target = $("#divMoreBtn"),
    152         /* 容器的offset Left、top和尺寸信息 */
    153         offset, offsetLeft, offsetTop,
    154         width, height,
    155         /* 弹出层的绝对坐标和宽度 */ 
    156         moreX, moreY,
    157         moreWidth,
    158         /* 空隙值 */
    159         spaceX=10, spaceY=5,
    160         /* more tabs*/
    161         ul;     
    162             
    163         offset = target.offset();
    164         offsetLeft = offset.left;
    165         offsetTop =offset.top;
    166         width = parseInt(target.css('width'));
    167         height = parseInt(target.css('height'));
    168         
    169         
    170         moreWidth = 200;
    171         moreX = offsetLeft + width - moreWidth;
    172         moreY = offsetTop + height + spaceY;
    173         /* 这样计算能让弹出层的右边和more按钮的右边对齐*/
    174         moreX < 0 && (moreWidth += (moreX - spaceX)) && (moreX = spaceX);
    175         
    176         //alert(offsetTop+" "+moreY+" "+height);
    177         var moreDiv = $("<div>"),
    178             moreTabsContainer = $("<div>"),
    179             moreSetting = $("<div>");
    180         moreDiv.attr('id','divMore');
    181         moreDiv.addClass("more-div");
    182         moreDiv.css({
    183             'width':moreWidth+'px',
    184             'left':moreX+'px',
    185             'top':moreY+'px'
    186         });
    187         
    188         moreTabsContainer.addClass('more-tabs-container');                
    189         ul = me.buildUl(me.config.realSize);
    190         moreTabsContainer.append(ul);
    191                 
    192         moreSetting.addClass('more-setting');
    193         moreSetting.html('设置');        
    194         moreSetting.toggle(
    195             function(){
    196                 this.innerHTML = "保存";
    197                 var uls = $("#divMore ul,#"+config.containerID+" ul");
    198                 for(var i =0;i<uls.length;i++){
    199                     uls[i].onclick=null;
    200                 }
    201                 me.unbindEventsWhenSettingTabs();
    202             },function(){
    203                 this.innerHTML = "设置";
    204                 var uls = $("#divMore ul,#"+config.containerID+" ul");
    205                 uls.each(function(i){                
    206                     me.bindTabsClickEvent(uls[i]);
    207                 });
    208                 me.bindEventsWhenMoreTabsShow();
    209             });
    210         
    211         moreDiv.append(moreTabsContainer).append(moreSetting);
    212         
    213         $(document.body).append(moreDiv);            
    214         stopPropagation(ev);
    215         
    216         /* more tabs显示后,重新绑定事件*/
    217         me.bindEventsWhenMoreTabsShow();
    218         
    219         /*阻止选中文本*/
    220         me.bankSelect();
    221 }
    222 jqTabMaster.prototype.hideMoreTabs = function(){
    223     $("#divMore").remove();
    224     
    225     /* more tabs隐藏后重新绑定事件*/
    226     jqTabMaster.prototype.bindEventsWhenMoreTabsHide();
    227 }
    228 jqTabMaster.prototype.unbindEventsWhenSettingTabs = function(){
    229     $(document).unbind('click');
    230     $("#divMoreBtn").unbind('click');
    231 }
    232 jqTabMaster.prototype.bindEventsWhenMoreTabsHide = function(){
    233     $(document).unbind('click');
    234     $("#divMoreBtn").unbind('click')
    235     .bind('click',function(){
    236         jqTabMaster.prototype.showMoreTabs();
    237     });
    238 }
    239 jqTabMaster.prototype.bindEventsWhenMoreTabsShow = function(){    
    240     /* 刷新more按钮的click事件。再点击click时也隐藏more*/
    241     $("#divMoreBtn").unbind('click')
    242     .bind('click',function(){
    243         jqTabMaster.prototype.hideMoreTabs();
    244     });;
    245     
    246     /* 点击more tabs容器外地地方时,隐藏more tabs*/
    247     $(document).unbind('click').bind('click', function(ev){
    248         var me = jqTabMaster.prototype,
    249             ev = ev || window.event,
    250             target = ev.target||ev.srcElement,
    251             isDivMore = target.id=="divMore",
    252             isBelong2DivMore = $(target).parents("#divMore").length>0;
    253         
    254         if(!isBelong2DivMore){
    255             me.hideMoreTabs();
    256         }
    257         else {
    258             stopPropagation(ev);
    259             return false;
    260         }
    261     });
    262 }
    263 
    264 jqTabMaster.prototype.bankSelect = function(){
    265     $("#divMore,#divMoreBtn,#"+jqTabMaster.prototype.config.containerID).bind('selectstart',function(){
    266         return false;
    267     })
    268     .css({
    269         '-moz-user-select':'none',
    270         '-webkit-user-select':'none',
    271         'user-select':'none'    
    272     });
    273 }

    css:

    View Code
     1 div{
     2     border:solid 1px #000;    
     3 }
     4 
     5 .container{
     6     border:solid 1px #000;
     7     display:block;
     8     float:left;
     9     height:50px;    
    10     margin:0px;
    11     padding:0px;
    12 }
    13 
    14 .container ul{
    15     float:left;
    16     list-style:none;
    17     margin:12px 5px 5px 5px;
    18     padding:0px;
    19     text-align: left;
    20 }
    21 .container ul li{
    22     border:solid 1px #f00;
    23     display:inline-block;
    24     margin: 5px 5px 105px 5px;
    25     overflow:visible;
    26     text-align:center;
    27     width:40px;
    28     
    29 }
    30 
    31 #divMoreBtn{
    32     border:solid 1px #000;
    33     display:block;
    34     float:left;
    35     height:50px;
    36     margin:0px 0px 0px 5px;
    37     vertical-align:bottom;
    38     width:35px;
    39 }
    40 
    41 #divMoreBtn span{
    42     display:block;
    43     line-height:60px;    
    44     text-align:center;
    45     vertical-align:middle;
    46 }
    47 
    48 .no-more{
    49     background-color#111;
    50     color:#ddd;
    51 }
    52 .more{
    53     background-color:#fff;
    54     color:#000;
    55 }
    56 .more-div{
    57     height:420px;
    58     position:absolute;
    59 }
    60 .more-div .more-tabs-container{
    61     height:360px;
    62     margin:5px;
    63     overflow-x:none;
    64     overflow-y:auto;
    65     position:relative;
    66 }
    67 .more-div .more-setting{
    68     color:#f00;
    69     display:block;
    70     font-weight:bold;
    71     line-height:40px;
    72     margin:8px 5px;
    73     height:40px;
    74     text-align:center;
    75     position:relative;
    76     vertical-align: bottom;
    77 }
    78 
    79 .more-tabs-container ul{
    80     margin:0px;
    81     padding: 0px;
    82     clear:both;
    83     float:left;
    84     list-style:none;    
    85 }
    86 
    87 .more-tabs-container ul li{
    88     border:solid 1px #DDDDDD;
    89     display:block;
    90     list-style:none;
    91     line-height:30px;    
    92     height:30px;
    93     margin:2px 10px 5px 10px;
    94     text-align:center;
    95     vertical-align:middle;
    96     width:120px;
    97 }

    html:

    View Code
     1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
     2 "http://www.w3.org/TR/html4/loose.dtd">
     3 <html xmlns="http://www.w3.org/1999/xhtml">
     4     <head>
     5         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     6         <title>Jq Tab Demo</title>
     7         <link href="css/css.css" rel="stylesheet"  />
     8     </head>
     9     <body>
    10         <h1>jq Tab</h1>
    11         
    12         
    13         <div id="div1">                 
    14         </div>
    15         <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
    16         <script type="text/javascript" src="js/jqTab.js"></script>
    17         <script type="text/javascript">
    18             var jqTab = new jqTabMaster();
    19             jqTab.initial({
    20                 containerID:"div1",
    21                 size:7,
    22                 items:[
    23                     {value:"1",text:"1"},
    24                     {value:"2",text:"2"},
    25                     {value:"3",text:"3"},
    26                     {value:"4",text:"4"},
    27                     {value:"5",text:"5"},
    28                     {value:"6",text:"6"},
    29                     {value:"7",text:"7"},
    30                     {value:"8",text:"8"},
    31                     {value:"9",text:"9"},
    32                     {value:"10",text:"10"}
    33                 ],
    34                 "300px",
    35                 callback:callback
    36             });
    37             function callback(value){
    38                 alert(value);
    39             }
    40             
    41         </script>
    42     </body>
    43 </html>

                                                今天就到这里

  • 相关阅读:
    android 本地字符串存取
    2020-07-17:线上一个服务有4个实例突然变得访问很慢,你会从什么地方入手找原因?
    2020-07-16:如何获得一个链表的倒数第n个元素?
    2020-07-15:死锁与活锁的区别,死锁与饥饿的区别?
    2020-07-14:es用过冷热分离吗?假如现在有些数据热变冷,有些数据冷变热,怎么解决?
    2020-07-28:已知sqrt (2)约等于 1.414,要求不用数学库,求sqrt (2)精确到小数点后 10 位。
    2020-07-29:从 innodb 的索引结构分析,为什么索引的 key 长度不能太长?
    2020-07-27:如何设计一个分布式文件系统,如何设计动态扩容和数据定位?
    2020-07-26:如何用 socket 编程实现 ftp 协议?
    2020-07-25:如何实现一个高效的单向链表逆序输出?
  • 原文地址:https://www.cnblogs.com/bee0060/p/2512441.html
Copyright © 2020-2023  润新知