今天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代码:注视可能不太清晰也不太规范,有兴趣的将就着看吧。
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