jquery插件一般是如此干的: $.fn.插件名称 = function(){},
把插件的名称加在.fn上,在源码里面其实是增添到构造函数的原型对象上,固然你没看过jquery的源代码,或者您早已看过,然而不明白怎么把插件伸张到fn上,那么本篇小说就能解答你的迷惑。关于jquery插件开发格局,可以参考我的那篇小说:[js高手之路]jquery插件开发实战-选项卡详解

关于选项卡这么些效果具体如何是好,不在那里详解,那个是入门级的功用,本文重在议论插件开发的架构,增加,以及参数设置。

假设您拔取过jquery的选项卡插件,或者此外类型的插件,他们一般都是那般调用的:

$( “.tab” ).tabs( {} )

$(“.tab”).tabs( function(){} );

一种是传递参数定制插件行为

一种是传递函数定制插件行为

$(“.tab”) 拔取到元素,然后回到的是jquery对象

tabs方法扩充在fn上就是扩充都jquery构造函数的原型对象上, 那么对象(
$(“.tab”) )调用原型对象上的点子( tabs )当然就顺手成章了。

为此jquery插件扩充本质就是: 构造函数 +
原型对象扩张方法

概念一个结构+原型的法门,上面代码的规律,我在这篇作品有详尽演说:[js高手之路]
设计方式种类课程 –
jQuery的链式调用与灵活的构造函数

图片 1图片 2

 1 var G = function( selectors, context ){
 2         return new G.fn.init( selectors, context );
 3     }
 4     G.fn = G.prototype = {
 5         length : 0,
 6         constructor : G,
 7         size : function(){
 8             return this.length;
 9         },
10         init : function( selector, context ){
11             this.length = 0;
12             context = context || document;
13             if ( selector.indexOf( '#' ) == 0 ){
14                 this[0] = document.getElementById( selector.substring( 1 ) );
15                 this.length = 1;
16             }else {
17                 var aNode = context.querySelectorAll( selector );
18                 for( var i = 0, len = aNode.length; i < len; i++ ) {
19                     this[i] = aNode[i];
20                 }
21                 this.length = len;
22             }
23             this.selector = selector;
24             this.context = context;
25             return this;
26         }
27     }
28 
29     G.fn.init.prototype = G.fn;

View Code

接下去,我们还要加上一个插件扩充机制:

图片 3图片 4

 1 G.extend = G.fn.extend = function () {
 2         var i = 1,
 3             len = arguments.length,
 4             dst = arguments[0],
 5             j;
 6         if (dst.length === undefined) {
 7             dst.length = 0;
 8         }
 9         if (i == len) {
10             dst = this;
11             i--;
12         }
13         for (; i < len; i++) {
14             for (j in arguments[i]) {
15                 dst[j] = arguments[i][j];
16                 dst.length++;
17             }
18         }
19         return dst;
20     };

View Code

在那篇小说:[js高手之路] 设计形式体系课程 –
jQuery的extend插件机制
 有详实的论述,extend插件扩张机制

像使用jquery一样暴光接口:

var $ = function( selectors, context ){
    return G( selectors, context );
}
window.$ = $;

那个插件的扩张机制和因素选取机制就成功了,若是要推而广之插件,只要在

G.fn上扩张插件的名称即可,如:

 1 G.fn.tabs = function( options ){
 2     options = options || {};
 3     var defaults = {
 4         contentClass : 'tab-content',
 5         navClass : 'tab-nav',
 6         activeClass : 'active',
 7         triggerElements : '*',
 8         activeIndex : 0,
 9         evType : 'click',
10         effect : 'none'
11     };
12 
13     var opt = G.extend( {}, defaults, options );
14     return this;
15 }

诸如此类,大家就在G的原型对象上增添了一个tabs( 选项卡 )插件

options可以定制插件的行为:

contentClass : 'tab-content',     选项卡内容区域的class名称
navClass : 'tab-nav',             标签卡区域的class名称 
activeClass : 'active',           标签卡默认选择的class名称:active
triggerElements : '*',            标签卡默认触发元素
activeIndex : 0,                  默认选中第几个标签卡
evType : 'click',                 选项卡触发的事件类型
effect : 'none'                   是否有过渡特效:如透明度


var opt = G.extend( {}, defaults, options );

这一段是把定制的陈设和默许配置合成到一个对象opt里面,前边的插件行为,就可以依据opt的布置举办定制,那是插件开发参数定制中,常用的一招。

那样做的补益,可防止患污染默许配置defaults

1  var tabContent = this[0].querySelector( "." + opt.contentClass );
2         var tabContentEle = tabContent.children;
3         var tabNavEle = this[0].querySelectorAll( "." + opt.navClass + '>' + opt.triggerElements );
4 
5         var _contentLen = tabContentEle.length;
6         var _index = opt.activeIndex;

收获相应的因素。

有了选项卡的要素和布置,大家就起先做业务处理(为具有选项卡添加处理的轩然大波,进行选项卡切换)

概念一个专程的目标_api = {}, 增加业务api

图片 5图片 6

 1 G.fn.tabs = function( options ){
 2         options = options || {};
 3         var defaults = {
 4             contentClass : 'tab-content',
 5             navClass : 'tab-nav',
 6             activeClass : 'active',
 7             triggerElements : '*',
 8             activeIndex : 0,
 9             evType : 'click',
10             effect : 'none'
11         };
12 
13         var opt = G.extend( {}, defaults, options );
14 
15         var tabContent = this[0].querySelector( "." + opt.contentClass );
16         var tabContentEle = tabContent.children;
17         var tabNavEle = this[0].querySelectorAll( "." + opt.navClass + '>' + opt.triggerElements );
18 
19         var _contentLen = tabContentEle.length;
20         var _index = opt.activeIndex;
21 
22         var _api = {};
23 
24         _api.setIndex = function( index ){
25             //当前标签加上active样式,其余标签删除active样式
26             for ( var i = 0; i < _contentLen; i++ ) {
27                 if ( tabNavEle[i].classList.contains( 'active' ) ) {
28                     tabNavEle[i].classList.remove('active');
29                 }
30             }
31             tabNavEle[index].classList.add( 'active' );
32             switch ( opt.effect ){
33                 case 'fade':
34                     break;
35                 default:
36                     for ( var i = 0; i < _contentLen; i++ ) {
37                         tabContentEle[i].style.display = 'none';
38                     }
39                     tabContentEle[index].style.display = 'block';
40                     _index = index;
41             }
42         }
43 
44         _api.setIndex( _index ); //默认的选项卡
45 
46         //所有的标签绑定事件
47         for( var i = 0, len = tabNavEle.length; i < len; i++ ) {
48             tabNavEle[i].index = i;
49             tabNavEle[i].addEventListener( opt.evType, function(){
50                 var i = this.index;
51                 _api.setIndex( i );
52             }, false );
53         }
54 
55         return this;
56     }

View Code

完整的插件代码:

图片 7图片 8

  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     G.fn.tabs = function( options ){
 56         options = options || {};
 57         var defaults = {
 58             contentClass : 'tab-content',
 59             navClass : 'tab-nav',
 60             activeClass : 'active',
 61             triggerElements : '*',
 62             activeIndex : 0,
 63             evType : 'click',
 64             effect : 'none'
 65         };
 66 
 67         var opt = G.extend( {}, defaults, options );
 68 
 69         var tabContent = this[0].querySelector( "." + opt.contentClass );
 70         var tabContentEle = tabContent.children;
 71         var tabNavEle = this[0].querySelectorAll( "." + opt.navClass + '>' + opt.triggerElements );
 72 
 73         var _contentLen = tabContentEle.length;
 74         var _index = opt.activeIndex;
 75 
 76         var _api = {};
 77 
 78         _api.setIndex = function( index ){
 79             //当前标签加上active样式,其余标签删除active样式
 80             for ( var i = 0; i < _contentLen; i++ ) {
 81                 if ( tabNavEle[i].classList.contains( 'active' ) ) {
 82                     tabNavEle[i].classList.remove('active');
 83                 }
 84             }
 85             tabNavEle[index].classList.add( 'active' );
 86             switch ( opt.effect ){
 87                 case 'fade':
 88                     break;
 89                 default:
 90                     for ( var i = 0; i < _contentLen; i++ ) {
 91                         tabContentEle[i].style.display = 'none';
 92                     }
 93                     tabContentEle[index].style.display = 'block';
 94                     _index = index;
 95             }
 96         }
 97 
 98         _api.setIndex( _index ); //默认的选项卡
 99 
100         //所有的标签绑定事件
101         for( var i = 0, len = tabNavEle.length; i < len; i++ ) {
102             tabNavEle[i].index = i;
103             tabNavEle[i].addEventListener( opt.evType, function(){
104                 var i = this.index;
105                 _api.setIndex( i );
106             }, false );
107         }
108 
109         return this;
110     }
111 
112     var $ = function( selectors, context ){
113         return G( selectors, context );
114     }
115     window.$ = $;
116 })();

View Code

选项卡布局:

图片 9图片 10

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <!--作者:ghostwu(吴华)-->
 5     <meta charset="UTF-8">
 6     <title>选项卡插件 - by ghostwu</title>
 7     <link rel="stylesheet" href="css/tab.css"/>
 8     <script src="./js/tab.js"></script>
 9     <script>
10         window.onload = function () {
11 //            console.log( $(".tab1 .tab-nav li") );
12 //            $( ".tab1" ).tabs( { 'evType' : 'mouseenter' } );
13             $( ".tab1" ).tabs();
14         }
15     </script>
16 </head>
17 <body>
18 <div class="main">
19     <div class="tab tab1">
20         <ul class="tab-nav">
21             <li class="active"><a href="javascript:;">标签1</a></li>
22             <li><a href="javascript:;">标签2</a></li>
23             <li><a href="javascript:;">标签3</a></li>
24             <li><a href="javascript:;">标签4</a></li>
25         </ul>
26         <div class="tab-content">
27             <p>内容1</p>
28             <p>内容2</p>
29             <p>内容3</p>
30             <p>内容4</p>
31         </div>
32     </div>
33 </div>
34 </body>
35 </html>

View Code

选项卡插件样式:

图片 11图片 12

 1 * {
 2     margin: 0;
 3     padding: 0;
 4 }
 5 body {
 6     font-size: 14px;
 7     font-family: Tahoma, Verdana,"Microsoft Yahei";
 8 }
 9 a{
10     text-decoration: none;
11     color:#000;
12 }
13 ul,li{
14     list-style-type: none;
15 }
16 img {
17     border:none;
18 }
19 .main {
20     width:960px;
21     margin:20px auto;
22 }
23 .tab{
24     margin: 0 auto 20px;
25 }
26 .tab1 .tab-nav{
27     margin-bottom:8px;
28 }
29 .tab .tab-nav {
30     overflow:hidden;
31 }
32 .tab1 .tab-nav .active{
33     border-bottom:1px solid #000;
34 }
35 .tab1 .tab-nav li {
36     float:left;
37     margin:0 10px;
38 }
39 .tab1 .tab-nav li a {
40     line-height:40px;
41     display:block;
42 }
43 .tab1 .tab-content {
44     height:250px;
45     overflow:hidden;
46 }
47 .tab1 .tab-content p {
48     height:250px;
49     background:#eee;
50 }

View Code

最终效果:

图片 13

 

相关文章

网站地图xml地图