重构完成:
把原来代码分成:
工具类 Tools
效果类 Effects
焦点图类
文字不行,直接上代码。
下面的代码把前面写到的效果都包括了。
对于ie 下面的渐隐渐现没有支持,有兴趣的可以支持一下。
1 <style> 2 #focus_view{ 3 overflow:hidden; 4 } 5 #focus_view td{ 6 height:200px; 7 } 8 9 </style> 10 <div id="focus_view"> 11 <table width="500" border="0" cellspacing="0" cellpadding="0"> 12 <tr> 13 <td style="background:#f00;"> </td> 14 <td style="background:#ff0;"> </td> 15 <td style="background:#f0f;"> </td> 16 <td style="background:#0f0;"> </td> 17 <td style="background:#000;"> </td> 18 <td style="background:#00f;"> </td> 19 </tr> 20 </table> 21 </div> 22 <button id="focus_prev">上一项</button><button id="focus_next">下一项</button> 23 24 <script> 25 /* 26 工具方法 27 主要有 28 anim 动画函数 29 getCss 获取CSS样式值 30 setCss 设置CSS样式值 31 setCssObj 对象形式设置CSS样式值 32 each 数组遍历,回调函数操作 33 debug 调试用 34 */ 35 36 var Tools=(function(undefined){ 37 var doc=this.document; 38 //简单封装了document.getElementById方法 39 var $=function(id){ 40 return doc.getElementById(id); 41 } 42 //创建标签,未使用 43 var createEl=function(tag){ 44 return doc.createElement(tag); 45 } 46 //动画函数 47 var anim=function(el,attr,time,callFn){ 48 if(typeof el==="string")el=$(el); 49 time=time||800; 50 var start=new Date(); 51 var old={}; 52 var name; 53 for(name in attr){ 54 old[name]=parseInt(getCss(el,name))||0; 55 } 56 (function step(){ 57 var diffTime=(new Date())-start; 58 var rate=diffTime/time; 59 for(var name in old){ 60 var val=old[name]+rate*(attr[name]-old[name]); 61 setCss(el,name,val); 62 } 63 64 if(rate<1){ 65 setTimeout(function(){step();},Math.min(20,time-diffTime)); 66 }else{ 67 for(names in attr){ 68 setCss(el,names,attr[names]); 69 } 70 callFn&&callFn.call(el); 71 } 72 73 })() 74 } 75 //未处理IE下透明的获取问题 76 function getCss(el,name){ 77 if(document.defaultView&&document.defaultView.getComputedStyle){ 78 return document.defaultView.getComputedStyle(el,null)[name]; 79 }else if(el.currentStyle){ 80 return el.currentStyle[name]; 81 } 82 return 0; 83 } 84 //未处理IE下透明的设置问题 85 var setCss=(function(){ 86 var cssNumber={//jQuery里的 87 "fillOpacity": true, 88 "fontWeight": true, 89 "lineHeight": true, 90 "opacity": true, 91 "orphans": true, 92 "widows": true, 93 "zIndex": true, 94 "zoom": true 95 } 96 var pxs={ 97 'width':true, 98 'height':true, 99 'left':true, 100 'right':true, 101 'top':true, 102 'bottom':true, 103 'marginLeft':true, 104 'marginTop':true 105 } 106 return function(el,name,val){ 107 var units=cssNumber[name]?'':pxs[name]?'px':''; 108 el.style[name]=val+units; 109 debug("el.style["+name+"]="+val+units) 110 } 111 })() 112 /*/当传入为样式对象 113 cssObj={ 114 100, 115 height:200, 116 display:'block' 117 } 118 */ 119 function setCssObj(el,cssObj){ 120 for(var name in cssObj){ 121 this.setCss(el,name,cssObj[name]); 122 } 123 } 124 //遍历数组 125 function each(arr,fn){ 126 for(var i=0,len=arr.length;i<len;i++){ 127 fn.call(arr[i],i,arr[i],arr); 128 } 129 } 130 //调试用 131 function debug(msg){ 132 //console.log(msg); 133 } 134 //直接混合对象 135 function mix(dest,src){ 136 for(var name in src){ 137 dest[name]=src[name]; 138 } 139 } 140 //返回接口函数 141 return { 142 $:$, 143 createEl:createEl, 144 anim:anim, 145 getCss:getCss, 146 setCss:setCss, 147 setCssObj:setCssObj, 148 each:each, 149 debug:debug, 150 mix:mix 151 } 152 })() 153 154 //效果管理,单例实现。 155 var Effects=(function(){ 156 var effects={}; 157 //添加默认方法 158 effects["def"]={ 159 init:function(arr){ 160 Focus.each(arr,function(i){ 161 Focus.setCss(arr[i],'display','none'); 162 }) 163 Focus.setCss(arr[0],'display',''); 164 }, 165 exec:function(index,arr){ 166 var that=this; 167 Focus.each(arr,function(i){ 168 Focus.setCss(arr[i],'display','none'); 169 }) 170 arr[index].style.display=""; 171 } 172 } 173 174 return{//返回 效果类管理方法 175 add:function(name,effectObj){ 176 effects[name]=effectObj; 177 }, 178 get:function(name){ 179 if(!name||!(name in effects)){ 180 return effects["def"]; 181 } 182 return effects[name]; 183 }, 184 del:function(name){ 185 delete effects[name]; 186 } 187 } 188 })() 189 190 /* 191 此焦点图代码用于示例,完成基本的演示功能,对于其它附加功能,在这里不与提供。 192 代码未经过全面的测试,如有需要使用者请自行修改并测试。 193 194 js代码: 195 "_":为私有属性,方法 196 197 */ 198 199 //构造函数 200 function Focus(options){ 201 this._focusItems=options.items||[];//焦点项为数组 202 this._callBackFn=options.callBackFn||function(){};//回调函数每次变化后调用 203 this._effect=Focus.Effects.get(options.effect||"def");//效果函数,用于焦点切换时的效果 204 this.autoPlay=options.autoPlay||true; 205 this._speed=options.speed||3000; 206 207 this._currentIndex=0;//当前的焦点索引 208 this._interval=null; 209 this.init(); 210 } 211 Tools.mix(Focus,Tools); 212 Tools.mix(Focus,{'Effects':Effects}); 213 //原型对象 214 Tools.mix(Focus.prototype,{ 215 constructor:Focus,//指明构造函数 216 init:function(){ 217 this._effect.init(this._focusItems); 218 if(this.autoPlay){ 219 this.play(); 220 } 221 }, 222 addFousItem:function(obj){//添加焦点项 public 223 if(!obj)return; 224 if(typeof obj==="string"){ 225 obj=document.getElementById(obj); 226 } 227 this._focusItem.push(obj); 228 },setEffect:function(name){ 229 this._effectFn=Focus.Effects.get(name); 230 }, 231 size:function(){//返回当前焦点项总长度 232 return this._focusItems.length; 233 }, 234 _check:function(num){//检查边界 235 return num<this.size()&&num>=0; 236 }, 237 getCurrentIndex:function(){//返回当前索引 238 return this._currentIndex; 239 }, 240 setIndex:function(num){//num 在边界内则设置 241 if(this._check(num)){ 242 this._currentIndex=num; 243 } 244 }, 245 goto:function(num){//设置到达的焦点项 246 this.setIndex(num); 247 this._effect.exec(this._currentIndex,this._focusItems); 248 this._callBackFn&&this._callBackFn.call(this,this._currentIndex,this._focusItems); 249 }, 250 prev:function(){//下一焦点项 251 var curIndex=this.getCurrentIndex(); 252 curIndex--; 253 if(!this._check(curIndex)){ 254 curIndex=this.size(); 255 curIndex--; 256 } 257 258 this.goto(curIndex); 259 }, 260 next:function(){//上一焦点项 261 var curIndex=this.getCurrentIndex(); 262 curIndex++; 263 if(!this._check(curIndex)){ 264 curIndex=0; 265 } 266 this.goto(curIndex); 267 }, 268 play:function(){ 269 var that=this; 270 that._interval= setInterval(function(){that.next()},that._speed) 271 }, 272 stop:function(){ 273 this._interval&&clearInterval(this._interval) 274 } 275 276 }) 277 278 279 280 281 282 283 284 /* 285 effectObj效果对象包含两个方法 286 接口: 287 init 对焦点图初始化使用,传入focusItems项的集合 288 exec 运行效果,效果针对当前项,传入参数index索引值,focusItems项集合 289 */ 290 291 292 293 /* 294 添加crossFade 渐隐渐现效果 295 */ 296 Focus.Effects.add("crossFade",{ 297 isExeced:false, 298 init:function(arr){ 299 Focus.each(arr,function(i){ 300 Focus.setCss(arr[i],'display','none'); 301 }) 302 Focus.setCss(arr[0],'display',''); 303 }, 304 exec:function(index,arr){ 305 var that=this; 306 if(!that.isExeced){ 307 Focus.each(arr,function(i){ 308 Focus.setCss(arr[i],'display','none'); 309 }) 310 Focus.setCssObj(arr[index],{'display':'','opacity':'0'}) 311 that.isExeced=true; 312 Focus.anim(arr[index],{"opacity":1},500,function(){ 313 that.isExeced=false; 314 }); 315 } 316 } 317 }) 318 319 /* 320 添加slider 滚动效果 321 */ 322 Focus.Effects.add("slider",{ 323 isExeced:false, 324 500, 325 height:200, 326 root:"focus_view", 327 direct:'left', 328 init:function(arr){ 329 var that=this; 330 var root=Focus.$(that.root); 331 Focus.each(arr,function(i){ 332 Focus.setCssObj(arr[i],{ 333 'position':'absolute', 334 'left':1000, 335 'display':'block', 336 'width':that.width, 337 'height':that.height 338 }) 339 }) 340 arr[0].style.left="0"; 341 Focus.setCssObj(root,{ 342 'position':'relative', 343 'overflow':'hidden', 344 'display':'block', 345 'width':that.width, 346 'height':that.height 347 }) 348 }, 349 exec:function(index,arr){ 350 var that=this; 351 if(!that.isExeced){ 352 Focus.each(arr,function(i){ 353 Focus.setCssObj(arr[i],{ 354 'zIndex':0, 355 'display':'none' 356 }); 357 }) 358 359 Focus.setCss(arr[(index==0?arr.length:index)-1],'display',''); 360 Focus.setCssObj(arr[index],{ 361 'zIndex':5, 362 'display':'', 363 'left':(that.direct=="left"?1:-1)*that.width 364 }); 365 that.isExeced=true; 366 Focus.anim(arr[index],{"left":0},500,function(){ 367 that.isExeced=false; 368 }); 369 370 371 } 372 } 373 }) 374 375 </script> 376 377 <script> 378 379 //测试用,只完成基本测试,后期会陆续添加一些效果,并对上面的代码进行扩展 380 /*var co=document.getElementById("focus_view") 381 Focus.Anim(co,{'width':0},500);*/ 382 //alert(Focus.getCss(co,"opacity")) 383 384 //console.log(Focus.Effects) 385 //以下为测试代码 386 387 var prev=document.getElementById("focus_prev"); 388 var next=document.getElementById("focus_next"); 389 390 var focusView=document.getElementById("focus_view"); 391 var focusItems=focusView.getElementsByTagName("td"); 392 //声明 393 var fos=new Focus({'items':focusItems,effect:'slider'}); 394 //设置切换效果 395 396 //后一项 397 next.onclick=function(){ 398 fos.next(); 399 } 400 //前一项 401 prev.onclick=function(){ 402 fos.prev(); 403 } 404 //停止 405 focusView.onmouseover=function(){ 406 fos.stop(); 407 } 408 //播放 409 focusView.onmouseout=function(){ 410 fos.play(); 411 } 412 </script>
写得比较急,有兴趣的攻城狮可留言讨论。(完)