2012.05.19

今天19号,周六, 昨天偷懒了,没学习没写博客就睡了,今天要多做点事情。所以一大早就打开编辑器了,虽然也是边玩边写··不过也算是有所输出吧。


今天还是继续写Jq Tab插件。

现在时23:38分,已经明显觉得困了,那么今天就到此为止。

今天实现了的功能为:

  为tab容器添加“更多”按钮。并为按钮绑定onclick事件:

     当更多的tabs隐藏时,生成包含more tabs的层并显示出来,同时切换按钮和document的onclick事件。

     当更多的tabs显示时,点击更多按钮盒document时都会隐藏更多tabs容器,并切换按钮事件和清空document onclick事件。

       在功能之外,今天整理了下代码,之前是把几乎全部代码都写到一个initial方法里的,今天整理了下,提取了几个其他的方法出来,但好像也没觉得代码有优美很多。看来我编码的功力还不够,还需要继续努力。

今天开发中遇到的问题包括:

因为需要切换更多按钮的事情,想到用jq 的toggle方法,但后来发现有点问题,因为toggle只会在指定的对象被点击时,才会切换事件,而我现在做的功能是当更多按钮或容器外部被点击时,都要切换事件,而当容器外部被点击时,more tabs 容器被隐藏,但更多按钮的事件却还没被切换。 为了解决这个问题,就用了比较原始的方法,先unbind再bind。如果哪位仁兄知道有较简便的实现方法,望告知,感激不尽。

想到得还没实现的功能:

1.提供callback函数接口

2.样式

3.调整应该显示的tabs,数量不超过size

4.每个tab可以接受任意数据格式

其中实现了前2个基本就能用了。第三个也在需求当中,暂时还没想到实现方法,但应该也可以实现得不太难。

总的来说,今天做的功能好像不多,做的时间嘛,大概2到3个小时。所以我的工作效率还是很低的。 以后也要尽量提高。那么今天就到这里。

这里贴上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 };
 27 
 28 jqTabMaster.prototype.buildUl = function(startIndex, endIndex, className){
 29     var config = this.config,
 30         items = config.items,
 31         max = items.length-1,
 32         startIndex = (typeof startindex =='undefined' || isNaN(startIndex))? 0:startIndex,
 33         endIndex = (typeof endIndex =='undefined' || isNaN(endIndex))? max:endIndex,
 34         ul = document.createElement("ul"),
 35         li;
 36         
 37     for(var i =startIndex;i<=endIndex;i++){
 38         li = document.createElement("li");
 39         li.innerHTML = items[i].text;
 40         li.value = items[i].value;
 41         ul.appendChild(li);
 42     }
 43     if(!!className){
 44         ul.className = className;
 45     }
 46     return ul;
 47 }
 48 
 49 jqTabMaster.prototype.initial = function(option){
 50     this.config.containerID = option.containerID;
 51     this.config.size = option.size;
 52     this.config.items = option.items;
 53     this.config.width = option.width;    
 54 
 55     var me = jqTabMaster.prototype,
 56         container = $("#"+this.config.containerID),
 57         iLen,
 58         ul, 
 59         showItems = [],
 60         moreItemsCount = 0;
 61 
 62     container.hide();
 63     container.addClass('container');
 64     container.css('width',this.config.width);
 65     container.css('overflow','hidden');
 66     /*增加”更多“按钮,默认为disabled*/
 67     container.css({'width':'-=40px'});
 68     var moreBtn = $("<div id='divMoreBtn' class='no-more'><span>更多</span></div>");
 69     moreBtn.insertAfter(container);
 70  
 71      /* 添加可显示的tabs */
 72      iLen = Math.min(this.config.items.length,this.config.size);
 73      ul = jqTabMaster.prototype.buildUl(0, iLen);
 74     container.append(ul);    
 75     
 76     container.show();
 77     /* Get Real Size 
 78          由于这里要调用offsetTop来判断是否超出边界,调用offset的参数会比较耗性能,
 79          现在是用从头开始便利数组获取的,之后可以使用二分法来进行快速查找,以提高性能。
 80      * */
 81     var displayInfo = me.getRealDisplayInfo();
 82     this.config.realSize = displayInfo.realSize;
 83     this.config.showItems = displayInfo.showItems;
 84     
 85     /* 当tab没有完全显示时 */    
 86     if((this.config.items.length - this.config.realSize)>0){
 87         $("#divMoreBtn").toggleClass('no-more');
 88         /*绑定显示更多tab事件*/
 89         $("#divMoreBtn").bind('click',function(ev){
 90             me.showMoreTabs(ev);
 91         });
 92     }
 93 }
 94 
 95 jqTabMaster.prototype.getRealDisplayInfo = function(){
 96     var me = jqTabMaster.prototype,
 97         config = me.config,
 98         realSize = 0,
 99         lis = $("#"+config.containerID+" ul li"),
100         showItems = [],
101         originOffsetTop=null;
102     
103     lis.each(function(i){
104         if(originOffsetTop==null){
105             originOffsetTop = this.offsetTop;
106             showItems.push(i);
107         } else if( this.offsetTop!=originOffsetTop){
108             return false;
109         }
110         realSize++;
111     });
112     return {realSize:realSize,showItems:showItems};
113 }
114 
115 /*
116  * params:
117  * ev: window.event
118  * me: jqTabMaster.prototype
119  */
120 jqTabMaster.prototype.showMoreTabs = function(ev){
121     var me = jqTabMaster.prototype,
122         ev = ev || window.event,
123         target = $("#divMoreBtn"),
124         /* 容器的offset Left、top和尺寸信息 */
125         offset, offsetLeft, offsetTop,
126         width, height,
127         /* 弹出层的绝对坐标和宽度 */ 
128         moreX, moreY,
129         moreWidth,
130         /* 空隙值 */
131         spaceX=10, spaceY=5,
132         /* more tabs*/
133         ul;     
134             
135         offset = target.offset();
136         offsetLeft = offset.left;
137         offsetTop =offset.top;
138         width = parseInt(target.css('width'));
139         height = parseInt(target.css('height'));
140         
141         
142         moreWidth = 200;
143         moreX = offsetLeft + width - moreWidth;
144         moreY = offsetTop + height + spaceY;
145         /* 这样计算能让弹出层的右边和more按钮的右边对齐*/
146         moreX < 0 && (moreWidth += (moreX - spaceX)) && (moreX = spaceX);
147         
148         //alert(offsetTop+" "+moreY+" "+height);
149         var moreDiv = $("<div>");
150         moreDiv.attr('id','divMore');
151         moreDiv.addClass("more-div");
152         moreDiv.css({
153             'width':moreWidth+'px',
154             'left':moreX+'px',
155             'top':moreY+'px'
156         });            
157         
158         ul = me.buildUl(me.config.realSize);
159         moreDiv.append(ul);
160         
161         $(document.body).append(moreDiv);            
162         stopPropagation(ev);
163         
164         /* more tabs显示后,重新绑定事件*/
165         me.bindEventsWhenMoreTabsShow();
166         
167         /*阻止选中文本*/
168         me.bankSelect();
169 }
170 jqTabMaster.prototype.hideMoreTabs = function(){
171     $("#divMore").remove();
172     
173     /* more tabs隐藏后重新绑定事件*/
174     jqTabMaster.prototype.bindEventsWhenMoreTabsHide();
175 }
176 jqTabMaster.prototype.bindEventsWhenMoreTabsHide = function(){
177     $(document).unbind('click');
178     $("#divMoreBtn").unbind('click')
179     .bind('click',function(){
180         jqTabMaster.prototype.showMoreTabs();
181     });
182 }
183 jqTabMaster.prototype.bindEventsWhenMoreTabsShow = function(){    
184     /* 刷新more按钮的click事件。再点击click时也隐藏more*/
185     $("#divMoreBtn").unbind('click')
186     .bind('click',function(){
187         jqTabMaster.prototype.hideMoreTabs();
188     });;
189     
190     /* 点击more tabs容器外地地方时,隐藏more tabs*/
191     $(document).bind('click', function(ev){
192         var me = jqTabMaster.prototype,
193             ev = ev || window.event,
194             target = ev.target||ev.srcElement,
195             isDivMore = target.id=="divMore",
196             isBelong2DivMore = $(target).parents("#divMore").length>0;
197         
198         if(!isBelong2DivMore){
199             me.hideMoreTabs();
200         }
201         else {
202             stopPropagation(ev);
203             return false;
204         }
205     });
206 }
207 
208 jqTabMaster.prototype.bankSelect = function(){
209     $("#divMore,#divMoreBtn,#"+jqTabMaster.prototype.config.containerID).bind('selectstart',function(){
210         return false;
211     })
212     .css({
213         '-moz-user-select':'none',
214         '-webkit-user-select':'none',
215         'user-select':'none'    
216     });
217 }

如果发现有什么问题欢迎批评指正,如果发现其中某些地方有更好的解决方法,也希望不吝赐教。 再次先谢过。

                                                      2012.05.19

原文地址:https://www.cnblogs.com/bee0060/p/2508856.html