你的位置:首页 > 软件开发 > Java > [js插件开发教程]实现一个比较完整的开源级选项卡插件

[js插件开发教程]实现一个比较完整的开源级选项卡插件

发布时间:2017-10-23 12:00:17
在这篇文章中,我实现了一个基本的选项卡功能:请猛击后面的链接>> [js插件开发教程]原生js仿jquery架构扩展开发选项卡插件.还缺少两个常用的切换(自动切换与透明度渐变),当然有朋友会说,还有左右,上下等等,这些动画会放在焦点图(幻灯片)插件系列.( ...

[js插件开发教程]实现一个比较完整的开源级选项卡插件

在这篇文章中,我实现了一个基本的选项卡功能:请猛击后面的链接>>   [js插件开发教程]原生js仿jquery架构扩展开发选项卡插件.

还缺少两个常用的切换(自动切换与透明度渐变),当然有朋友会说,还有左右,上下等等,这些动画会放在焦点图(幻灯片)插件系列.

(自动切换,停止控制,透明度渐变 ) 效果预览:

[js插件开发教程]实现一个比较完整的开源级选项卡插件

自动切换的实现:

这个思路很简单,开启定时器,让选项卡的索引+1,加到4的时候(选项卡的长度)从0开始

传统做法:

index = 0

index++

if ( index == 4 ) {

index = 0

}

小技巧(估计很多人都没有用过):

var i = ( index + 1 ) %  4

index为当前选中的选项卡 索引

当index = 0,他下一张就是1,  通过上面的取余操作,i = 1

当index = 3,他下一张就是0, 通过上面的取余操作,i = 0

这种方法不需要判断边界,只需要一句代码。在实际开发中,把那个4替换成选项卡的长度

好了,关键的思路和技巧有了,我们开始拼接框架了:

 1   var defaults = { 2    contentClass : 'tab-content', 3    navClass : 'tab-nav', 4    activeClass : 'active', 5    triggerElements : '*', 6    activeIndex : 0, 7    evType : 'click', 8    effect : 'none', 9    auto : false,10    delay : 3000,11    duration : 100012   };

defaults参数,增加几个配置:

effect: none(没有特效) / fade( 透明度切换 )

auto: false(不会自动切换) / true ( 开启自动切换 )

delay : 多少时间 切换一个选项卡

duration: 透明度开启,这个才会用到,表示,多长时间内 完成透明度的切换

1 if ( options.effect == 'fade' ) {2    tabContent.style.position = 'relative';3    for( var i = 0; i < tabContentEle.length; i++ ) {4     tabContentEle[i].style.position = 'absolute';5    }6    tabContentEle[opt.activeIndex].style.zIndex = _contentLen + 1;7    opt.delay += opt.duration;8   }

当开启透明度变化的时候,把选项卡元素设置成定位方式,当前选中的选项卡,层级为最高!!! ( 如果不是最高层级,那么默认是最后一个选项卡在最上面,所以 “内容4” 就会在最上层,显然不是我们想要的结果)层级+定位 这一招也很常用,经常用来做显示隐藏,和透明度变化.

根据opt配置,判断是否开启了auto自动切换功能

 1 //是否自动播放 2   if ( opt.auto ) { 3    for( var i = 0 ; i < tabNavEle.length; i++ ){ 4     tabNavEle[i].index = i; 5     tabNavEle[i].onmouseover = function(){ 6      _api.stop(); 7      _api.setIndex( this.index ); 8     }; 9     tabNavEle[i].onmouseout = function(){10      _api.start();11      _api.setIndex( this.index );12     };13    }14    _api.start();15   }

如果开启了,做两件事情:

1,调用start()函数,让索引+1

2,选项卡导航部分,添加事件控制 自动播放的暂停和开始

start与stop方法?

 1 _api.stop = function(){ 2    timer && clearInterval( timer ); 3   }; 4  5   _api.start = function(){ 6    _api.stop(); 7    timer = setInterval( function(){ 8     _api.next(); 9    }, opt.delay );10   };

调用next方法,你应该猜得到next方法做的事情就是索引+1 吧

1 _api.next = function(){2    var i = ( _index + 1 ) % _contentLen;3    _api.setIndex( i );4   };

索引+1之后,再切换选项卡

最后在setIndex方法:增加透明度变化

 1 if ( _index != index ) { 2       tabContentEle[_index].style.zIndex = _contentLen + 1; 3       for (var i = 0; i < tabContentEle.length; i++) { 4        if (i != _index) { 5         tabContentEle[i].style.zIndex = ( index + _contentLen - ( i + 1 ) ) % _contentLen + 1; 6         tabContentEle[i].style.opacity = 1; 7        } 8       } 9       animate(tabContentEle[_index], {'opacity': 0}, function () {10        tabContentEle[_index].style.zIndex = ( index + _contentLen - ( _index + 1 ) ) % _contentLen + 1;11        _index = index;12       });13      }

完整的js代码有220行:

[js插件开发教程]实现一个比较完整的开源级选项卡插件[js插件开发教程]实现一个比较完整的开源级选项卡插件
 1 /** 2  * Created by ghostwu(吴华). 3 */ 4 (function(){ 5  var G = function( selectors, context ){ 6   return new G.fn.init( selectors, context ); 7  } 8  G.fn = G.prototype = { 9   length : 0, 10   constructor : G, 11   size : function(){ 12    return this.length; 13   }, 14   init : function( selector, context ){ 15    this.length = 0; 16    context = context || document; 17    if ( selector.indexOf( '#' ) == 0 ){ 18     this[0] = document.getElementById( selector.substring( 1 ) ); 19     this.length = 1; 20    }else { 21     var aNode = context.querySelectorAll( selector ); 22     for( var i = 0, len = aNode.length; i < len; i++ ) { 23      this[i] = aNode[i]; 24     } 25     this.length = len; 26    } 27    this.selector = selector; 28    this.context = context; 29    return this; 30   } 31  } 32  33  G.fn.init.prototype = G.fn; 34  G.extend = G.fn.extend = function () { 35   var i = 1, 36    len = arguments.length, 37    dst = arguments[0], 38    j; 39   if (dst.length === undefined) { 40    dst.length = 0; 41   } 42   if (i == len) { 43    dst = this; 44    i--; 45   } 46   for (; i < len; i++) { 47    for (j in arguments[i]) { 48     dst[j] = arguments[i][j]; 49     dst.length++; 50    } 51   } 52   return dst; 53  }; 54  55  function css(obj, attr, value) { 56   if (arguments.length == 3) { 57    obj.style[attr] = value; 58   } else { 59    if (obj.currentStyle) { 60     return obj.currentStyle[attr]; 61    } else { 62     return getComputedStyle(obj, false)[attr]; 63    } 64   } 65  } 66  67  function animate(obj, attr, fn) { 68   clearInterval(obj.timer); 69   var cur = 0; 70   var target = 0; 71   var speed = 0; 72   var start = new Date().getTime();//起始时间 73   obj.timer = setInterval(function () { 74    var bFlag = true; 75    for (var key in attr) { 76     if (key == 'opacity') { 77      cur = css(obj, 'opacity') * 100; 78     } else { 79      cur = parseInt(css(obj, key)); 80     } 81     target = attr[key]; 82     speed = ( target - cur ) / 8; 83     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); 84     if (cur != target) { 85      bFlag = false; 86      if (key == 'opacity') { 87       obj.style.opacity = ( cur + speed ) / 100; 88       obj.style.filter = "alpha(opacity:" + ( cur + speed ) + ")"; 89      } else { 90       obj.style[key] = cur + speed + "px"; 91      } 92     } 93    } 94    if (bFlag) { 95     var end = new Date().getTime();//结束时间 96     console.log( '总计:', ( end - start ) ); 97     clearInterval(obj.timer); 98     fn && fn.call(obj); 99    }100   }, 30 );101  }102 103  G.fn.tabs = function( options ){104   options = options || {};105   var defaults = {106    contentClass : 'tab-content',107    navClass : 'tab-nav',108    activeClass : 'active',109    triggerElements : '*',110    activeIndex : 0,111    evType : 'click',112    effect : 'none',113    auto : false,114    delay : 3000,115    duration : 1000116   };117 118   var opt = G.extend( {}, defaults, options );119 120   var tabContent = this[0].querySelector( "." + opt.contentClass );121   var tabContentEle = tabContent.children;122   var tabNavEle = this[0].querySelectorAll( "." + opt.navClass + '>' + opt.triggerElements );123 124   var _contentLen = tabContentEle.length; //选项卡个数125   var _index = opt.activeIndex;126   var timer = null;127 128   if ( options.effect == 'fade' ) {129    tabContent.style.position = 'relative';130    for( var i = 0; i < tabContentEle.length; i++ ) {131     tabContentEle[i].style.position = 'absolute';132    }133    tabContentEle[opt.activeIndex].style.zIndex = _contentLen + 1;134    opt.delay += opt.duration;135   }136 137   var _api = {};138 139   _api.next = function(){140    var i = ( _index + 1 ) % _contentLen;141    _api.setIndex( i );142   };143 144   _api.stop = function(){145    timer && clearInterval( timer );146   };147 148   _api.start = function(){149    _api.stop();150    timer = setInterval( function(){151     _api.next();152    }, opt.delay );153   };154 155   _api.setIndex = function( index ){156    //当前标签加上active样式,其余标签删除active样式157    for ( var i = 0; i < _contentLen; i++ ) {158     if ( tabNavEle[i].classList.contains( 'active' ) ) {159      tabNavEle[i].classList.remove('active');160     }161    }162    tabNavEle[index].classList.add( 'active' );163    switch ( opt.effect ){164     case 'fade':165      if ( _index != index ) {166       tabContentEle[_index].style.zIndex = _contentLen + 1;167       for (var i = 0; i < tabContentEle.length; i++) {168        if (i != _index) {169         tabContentEle[i].style.zIndex = ( index + _contentLen - ( i + 1 ) ) % _contentLen + 1;170         tabContentEle[i].style.opacity = 1;171        }172       }173       animate(tabContentEle[_index], {'opacity': 0}, function () {174        tabContentEle[_index].style.zIndex = ( index + _contentLen - ( _index + 1 ) ) % _contentLen + 1;175        _index = index;176       });177      }178      break;179     default:180      for ( var i = 0; i < _contentLen; i++ ) {181       tabContentEle[i].style.display = 'none';182      }183      tabContentEle[index].style.display = 'block';184      _index = index;185    }186   }187 188   _api.setIndex( _index ); //默认的选项卡189 190   //所有的标签绑定事件191   for( var i = 0, len = tabNavEle.length; i < len; i++ ) {192    tabNavEle[i].index = i;193    tabNavEle[i].addEventListener( opt.evType, function(){194     var i = this.index;195     _api.setIndex( i );196    }, false );197   }198 199   //是否自动播放200   if ( opt.auto ) {201    for( var i = 0 ; i < tabNavEle.length; i++ ){202     tabNavEle[i].index = i;203     tabNavEle[i].onmouseover = function(){204      _api.stop();205      _api.setIndex( this.index );206     };207     tabNavEle[i].onmouseout = function(){208      _api.start();209      _api.setIndex( this.index );210     };211    }212    _api.start();213   }214 215   return this;216  }217 218  var $ = function( selectors, context ){219   return G( selectors, context );220  }221  window.$ = $;222 })();
View Code

 

原标题:[js插件开发教程]实现一个比较完整的开源级选项卡插件

关键词:JS

JS
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。