[js插件开发教程]一步步开发一个可以定制配置的隔行变色小插件

隔行变色功能,不用js,直接用css伪类就可以做,这个实例可以作为js插件开发很好的入门级实例。本文实现的隔行变色包括以下功能:

1,支持2种常用结构共存( div元素 和 表格类型 )

2,一个页面内支持不同模块隔行变色,分别管理

3,可以定制的配置有:

奇/偶数行的背景颜色

特定的模块加上隔行变色

当前激活行的颜色

隔行变色的元素类型定制

{
'activeClass' : 'active',
'evenClass' : 'even-color',
'oddClass' : 'odd-color',
'ele' : 'div',
'context' : document
}; 
4,可以扩展其他插件
 
点击run code按钮预览效果

 
我们要实现的是多个插件功能【选项卡,全选,不选,反选,轮播,弹窗,分页等常用插件】,所以第一步,要做一个简单的模块架构,这里,我采用的是字面量单例模式+命名空间
 1 (function(){
 2     /*
 3         隔行变色
 4         选项卡
 5         全选不选反选
 6     */
 7     var ghostwu = {};
 8     /***************隔行变色开始***************/
 9     ghostwu.BgColor = {
10     };
11     ghostwu.BgColor.init = function(){
12     }
13     ghostwu.BgColor.setBgColor = function(){
14     }
15     ghostwu.BgColor.hover = function(){
16     }
17     ghostwu.BgColor.addBg = function(){
18     }
19     ghostwu.BgColor.removeBg = function(){
20     }
21     /***************隔行变色结束***************/
22 
23     /***************选项卡开始***************/
24     ghostwu.Tab = {
25     };
26     ghostwu.Tab.init = function(){
27     }
28     ghostwu.Tab.bindEvent = function(){
29     }
30     ghostwu.BgColor.switchTab = function(){
31     }
32     /***************选项卡结束***************/
33 
34     window.g = ghostwu;
35 })();

一、首先定义一个一级的命名空间 ghostwu = {},然后通过window对象 暴露这个对象 给外部使用

接下来开发的插件,只要加在我的一级命名空间中即可,如:

ghostwu.BgColor

ghostwu.Tab

ghostwu.Page

ghostwu.Module

........等等

插件的具体方法,在二级命名空间继续增加,如:

ghostwu.BgColor.init

为隔行变色插件( BgColor ) 添加一个初始化方法( init )

二、实现一个不能定制配置的隔行变色功能

demo.js代码

 1 var ghostwu = {};
 2     /***************隔行变色开始***************/
 3     ghostwu.BgColor = {
 4         oldColor : null
 5     };
 6     ghostwu.BgColor.init = function(){
 7         this.aDiv = document.querySelectorAll( "div" );
 8     }
 9     ghostwu.BgColor.setBgColor = function(){
10         for( var i = 0; i < this.aDiv.length; i++ ){
11             if ( i % 2 == 0  ){
12                 this.aDiv[i].className = 'even-color';
13             }else {
14                 this.aDiv[i].className = 'odd-color';
15             }
16         }
17     }
18     ghostwu.BgColor.hover = function(){
19         var that = this;
20         for( var i = 0 ; i < this.aDiv.length; i++ ){
21             this.aDiv[i].onmouseover = function(){
22                 that.addBg( this );
23             }
24             this.aDiv[i].onmouseout = function(){
25                 that.removeBg( this );
26             }
27         }
28     }
29     ghostwu.BgColor.addBg = function( curObj ){
30         this.oldColor = curObj.className;
31         curObj.className = 'active';
32     }
33     ghostwu.BgColor.removeBg = function( curObj ){
34         curObj.className = this.oldColor;
35     }
36     /***************隔行变色结束***************/

html页面布局代码

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>隔行变色 - by ghostwu</title>
 8     <style>
 9         div{
10             margin:10px;
11             padding:20px;
12             border:1px solid #ccc;
13         }
14         .even-color {
15             background:#ccc;
16         }
17         .odd-color {
18             background: #eee;
19         }
20         .active {
21             background:yellow;
22         }
23     </style>
24     <script src="./lib/demo.js"></script>
25     <script>
26         window.onload = function(){
27             var oBg = g.BgColor;
28             oBg.init();
29             oBg.setBgColor();
30             oBg.hover();
31         }
32     </script>
33 </head>
34 <body>
35     <div></div>
36     <div></div>
37     <div></div>
38     <div></div>
39     <div></div>
40     <div></div>    
41 </body>
42 </html>

至此,一个简单的隔行变色功能就完成了,但是不能称之为插件,因为这个功能现在是写死的

三、把可能变化的部分抽象出来变成配置
可能变化的部分有:
1,元素,这里我们的布局是div,隔行变色也有可能是表格
2,class样式,这里是even-color,odd-color, active,我们要支持class定制
接下来,我们添加一个json配置,设置一些默认配置,然后允许初始化的时候 定制样式名称和元素
 1 var ghostwu = {};
 2     /***************隔行变色开始***************/
 3     ghostwu.BgColor = {
 4         oldColor : null,
 5         opt : {
 6             'activeClass' : 'active',
 7             'oddClass' : 'odd-color',
 8             'evenClass' : 'even-color',
 9             'ele' : 'div'
10         }
11     };
12     ghostwu.BgColor.init = function(){
13         this.elements = document.querySelectorAll( this.opt['ele'] );
14     }
15     ghostwu.BgColor.setBgColor = function(){
16         for( var i = 0; i < this.elements.length; i++ ){
17             if ( i % 2 == 0  ){
18                 this.elements[i].className = this.opt['evenClass'];
19             }else {
20                 this.elements[i].className = this.opt['oddClass'];
21             }
22         }
23     }
24     ghostwu.BgColor.hover = function(){
25         var that = this;
26         for( var i = 0 ; i < this.elements.length; i++ ){
27             this.elements[i].onmouseover = function(){
28                 that.addBg( this );
29             }
30             this.elements[i].onmouseout = function(){
31                 that.removeBg( this );
32             }
33         }
34     }
35     ghostwu.BgColor.addBg = function( curObj ){
36         this.oldColor = curObj.className;
37         curObj.className = this.opt['activeClass'];
38     }
39     ghostwu.BgColor.removeBg = function( curObj ){
40         curObj.className = this.oldColor;
41     }
42     /***************隔行变色结束***************/

经过修改之后,我们就可以通过 opt这个json 配置样式和元素结构了, 接下来,我们就得增加参数配置了

四、参数配置

只需要在demo.js代码中,加入一个for循环,把参数的配置复制给opt即可

1 ghostwu.BgColor.init = function( option ){
2     for( var key in option ){
3         this.opt[key] = option[key];
4     }
5     this.elements = document.querySelectorAll( this.opt['ele'] );
6 }

html测试页面修改如下:

 1 <style>
 2     div{
 3         margin:10px;
 4         padding:20px;
 5         border:1px solid #ccc;
 6     }
 7     .even-color2 {
 8         background:#000;
 9     }
10     .odd-color2 {
11         background: #666;
12     }
13     .current {
14         background:#08f;
15     }
16 </style>
17 <script src="./lib/demo.js"></script>
18 <script>
19     window.onload = function(){
20         var oBg = g.BgColor;
21         oBg.init({
22             'activeClass' : 'current',
23             'evenClass' : 'even-color2',
24             'oddClass' : 'odd-color2'
25         });
26         oBg.setBgColor();
27         oBg.hover();
28     }
29 </script>

五、完善元素的配置

在第四步中,class都可以定制了,但是ele还不能定制,这个ele就是控制隔行变色的结构

修改init函数如下:

 1 ghostwu.BgColor.init = function( option ){
 2     for( var key in option ){
 3         this.opt[key] = option[key];
 4     }
 5     if ( this.opt['ele'] == 'div' ) {
 6         this.elements = document.querySelectorAll( this.opt['ele'] );
 7     }else{
 8         this.elements = document.querySelectorAll( this.opt['ele'] + " tr" );
 9         this.elements = [].slice.call( this.elements );
10         for( var i = 0 ; i < this.elements.length; i++ ){
11             if ( this.elements[i].children[0].nodeName.toLowerCase() == 'th' ) {
12                 this.elements.splice( i, 1 );
13             }
14         }
15     }
16 }

测试页面的代码修改如下:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>隔行变色 - by ghostwu</title>
  9     <style>
 10         table {
 11             border-collapse: collapse;
 12             width: 100%;
 13         }
 14 
 15         th,
 16         td {
 17             padding: 10px 30px;
 18             border: 1px solid #ccc;
 19         }
 20         div {
 21             margin: 10px;
 22             padding: 20px;
 23             border: 1px solid #ccc;
 24         }
 25 
 26         .even-color2 {
 27             background: #000;
 28         }
 29 
 30         .odd-color2 {
 31             background: #666;
 32         }
 33 
 34         .current {
 35             background: #08f;
 36         }
 37     </style>
 38     <script src="./lib/demo.js"></script>
 39     <script>
 40         window.onload = function () {
 41             var oBg = g.BgColor;
 42             oBg.init({
 43                 'activeClass': 'current',
 44                 'evenClass': 'even-color2',
 45                 'oddClass': 'odd-color2'
 46             });
 47             oBg.setBgColor();
 48             oBg.hover();
 49 
 50             var oBg2 = g.BgColor;
 51             oBg2.init({
 52                 'activeClass': 'current',
 53                 'evenClass': 'even-color2',
 54                 'oddClass': 'odd-color2',
 55                 'ele' : 'table'
 56             });
 57             oBg2.setBgColor();
 58             oBg2.hover();
 59         }
 60 
 61     </script>
 62 </head>
 63 
 64 <body>
 65     <div></div>
 66     <div></div>
 67     <div></div>
 68     <div></div>
 69     <div></div>
 70     <div></div>
 71     <table>
 72         <tr>
 73             <th>姓名</th>
 74             <th>性别</th>
 75             <th>年龄</th>
 76         </tr>
 77         <tr>
 78             <td>ghostwu</td>
 79             <td>man</td>
 80             <td>20</td>
 81         </tr>
 82         <tr>
 83             <td>ghostwu</td>
 84             <td>man</td>
 85             <td>20</td>
 86         </tr>
 87         <tr>
 88             <td>ghostwu</td>
 89             <td>man</td>
 90             <td>20</td>
 91         </tr>
 92         <tr>
 93             <td>ghostwu</td>
 94             <td>man</td>
 95             <td>20</td>
 96         </tr>
 97         <tr>
 98             <td>ghostwu</td>
 99             <td>man</td>
100             <td>20</td>
101         </tr>
102         <tr>
103             <td>ghostwu</td>
104             <td>man</td>
105             <td>20</td>
106         </tr>
107         <tr>
108             <td>ghostwu</td>
109             <td>man</td>
110             <td>20</td>
111         </tr>
112     </table>
113 </body>
114 
115 </html>

至此,我们开发的功能,勉强算个插件了,但是,不能按区域控制,比如页面上有10个div, 分成2部分,一部分有5个div,另外一部分也是5个,我想其中一部分div加上隔行变色效果。另外一部分不加.

六、分块控制

其实很简单,就是不要用document去获取元素,document获取到的元素是所有的元素,所以我们在配置中加一个上下文的配置,可以限定获取某部分满足条件的节点.
修改demo.js对应部分的代码如下:
 1 ghostwu.BgColor = {
 2         oldColor : null,
 3         opt : {
 4             'activeClass' : 'active',
 5             'oddClass' : 'odd-color',
 6             'evenClass' : 'even-color',
 7             'ele' : 'div',
 8             'context' : document
 9         }
10     };
11 ghostwu.BgColor.init = function( option ){
12     for( var key in option ){
13         this.opt[key] = option[key];
14     }
15     var cxt = this.opt['context'];
16     if ( typeof cxt === 'string' ){
17         cxt = document.querySelector( this.opt['context'] );
18     }
19     if ( this.opt['ele'] == 'div' ) {
20         this.elements = cxt.querySelectorAll( this.opt['ele'] );
21     }else{
22         this.elements = cxt.querySelectorAll( this.opt['ele'] + " tr" );
23         this.elements = [].slice.call( this.elements );
24         for( var i = 0 ; i < this.elements.length; i++ ){
25             if ( this.elements[i].children[0].nodeName.toLowerCase() == 'th' ) {
26                 this.elements.splice( i, 1 );
27             }
28         }
29     }
30 }

修改html页面代码如下:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>隔行变色 - by ghostwu</title>
  9     <style>
 10         table {
 11             border-collapse: collapse;
 12             width: 100%;
 13         }
 14 
 15         th,
 16         td {
 17             padding: 10px 30px;
 18             border: 1px solid #ccc;
 19         }
 20 
 21         .even-color {
 22             background: #ccc;
 23         }
 24 
 25         .odd-color {
 26             background: #eee;
 27         }
 28 
 29         .even-color2 {
 30             background: #000;
 31         }
 32 
 33         .odd-color2 {
 34             background: #666;
 35         }
 36 
 37         .current {
 38             background: yellow;
 39         }
 40 
 41         .active {
 42             background: #09f;
 43         }
 44 
 45         #box div,
 46         #box2 div {
 47             margin: 10px;
 48             padding: 10px;
 49             border: 1px solid #ccc;
 50         }
 51     </style>
 52     <script src="./lib/demo.js"></script>
 53     <script>
 54         window.onload = function () {
 55             var oBg = g.BgColor;
 56             oBg.init({
 57                 'activeClass': 'current',
 58                 'evenClass': 'even-color2',
 59                 'oddClass': 'odd-color2',
 60                 'context' : '#box'
 61             });
 62             oBg.setBgColor();
 63             oBg.hover();
 64 
 65             var oBg3 = g.BgColor;
 66             oBg3.init({
 67                 'activeClass': 'active',
 68                 'evenClass': 'even-color',
 69                 'oddClass': 'odd-color',
 70                 'context' : '#box2'
 71             });
 72             oBg3.setBgColor();
 73             oBg3.hover();
 74 
 75             var oBg2 = g.BgColor;
 76             oBg2.init({
 77                 'activeClass': 'current',
 78                 'evenClass': 'even-color2',
 79                 'oddClass': 'odd-color2',
 80                 'ele': 'table',
 81                 'context' : document
 82             });
 83             oBg2.setBgColor();
 84             oBg2.hover();
 85         }
 86     </script>
 87 </head>
 88 
 89 <body>
 90     <div id="box">
 91         <div></div>
 92         <div></div>
 93         <div></div>
 94         <div></div>
 95     </div>
 96     <div id="box2">
 97         <div></div>
 98         <div></div>
 99         <div></div>
100         <div></div>
101         <div></div>
102         <div></div>
103     </div>
104     <table>
105         <tr>
106             <th>姓名</th>
107             <th>性别</th>
108             <th>年龄</th>
109         </tr>
110         <tr>
111             <td>ghostwu</td>
112             <td>man</td>
113             <td>20</td>
114         </tr>
115         <tr>
116             <td>ghostwu</td>
117             <td>man</td>
118             <td>20</td>
119         </tr>
120         <tr>
121             <td>ghostwu</td>
122             <td>man</td>
123             <td>20</td>
124         </tr>
125         <tr>
126             <td>ghostwu</td>
127             <td>man</td>
128             <td>20</td>
129         </tr>
130         <tr>
131             <td>ghostwu</td>
132             <td>man</td>
133             <td>20</td>
134         </tr>
135         <tr>
136             <td>ghostwu</td>
137             <td>man</td>
138             <td>20</td>
139         </tr>
140         <tr>
141             <td>ghostwu</td>
142             <td>man</td>
143             <td>20</td>
144         </tr>
145     </table>
146 </body>
147 
148 </html>

这样我们就可以达到分块控制的目的,但是,如果你仔细一点,应该能发现一个问题,activeClass设置的样式产生了覆盖,3个区域不能定制activeClass。这个就是单例模式无法解决的问题,我们可以通过构造函数解决

七、构造函数解决属性配置覆盖的问题

最终版demo.js文件
 1 (function(){
 2     /*
 3         隔行变色
 4         选项卡
 5         全选不选反选
 6     */
 7     var ghostwu = {};
 8 
 9     /***************隔行变色开始***************/
10     ghostwu.BgColor = {
11         Bg : function( option ){
12             return new ghostwu.BgColor.init( option );
13         }
14     };
15     ghostwu.BgColor.init = function( option ){
16         this.oldColor = null;
17         this.opt = {
18             'activeClass' : 'active',
19             'evenClass' : 'even-color',
20             'oddClass' : 'odd-color',
21             'ele' : 'div',
22             'context' : document
23         }; //存储默认配置
24         for( var key in option ){
25             this.opt[key] = option[key];
26         }
27         if ( this.opt.ele == 'div' ){
28             var curCxt = this.opt.context;
29             if ( typeof this.opt['context'] === 'string' ) {
30                 curCxt = document.querySelector( this.opt['context'] );
31             }
32             this.elements = curCxt.querySelectorAll( this.opt.ele );
33         }else {
34             this.elements = this.opt.context.querySelectorAll( this.opt.ele + ' tr' );
35             for( var i = 0; i < this.elements.length; i++ ){
36                 if( this.elements[i].children[0].nodeName.toLowerCase() == 'th'){
37                     this.elements = [].slice.call( this.elements );
38                     this.elements.splice( i, 1 );
39                 }
40             }
41         }
42     }
43     ghostwu.BgColor.init.prototype.setBgColor = function(){
44         for( var i = 0 ; i < this.elements.length; i++ ){
45             if ( i % 2 == 0 ) {
46                 this.elements[i].className = this.opt['evenClass'];
47             }else {
48                 this.elements[i].className = this.opt['oddClass'];
49             }
50         }
51     }
52     ghostwu.BgColor.init.prototype.hover = function(){
53         var that = this;
54         for( var i = 0 ; i < this.elements.length; i++ ){
55             this.elements[i].onmouseover = function(){
56                 that.addBg( this );
57             };
58             this.elements[i].onmouseout = function(){
59                 that.removeBg( this );
60             }
61         }
62     }
63     ghostwu.BgColor.init.prototype.addBg = function( curObj ){
64         this.oldColor = curObj.className;
65         curObj.className = this.opt['activeClass'];
66     }
67     ghostwu.BgColor.init.prototype.removeBg = function( curObj ){
68         curObj.className = this.oldColor;
69     }
70     /***************隔行变色结束***************/
71 
72 
73 
74 
75     window.g = ghostwu;
76 })();

页面测试代码:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>隔行变色插件开发 - by ghostwu</title>
  9     <style>
 10         table {
 11             border-collapse: collapse;
 12             width: 100%;
 13         }
 14 
 15         th,
 16         td {
 17             padding: 10px 30px;
 18             border: 1px solid #ccc;
 19         }
 20 
 21         .even-color {
 22             background: #ccc;
 23         }
 24 
 25         .odd-color {
 26             background: #eee;
 27         }
 28 
 29         .even-color2 {
 30             background: #000;
 31         }
 32 
 33         .odd-color2 {
 34             background: #666;
 35         }
 36 
 37         .current {
 38             background: yellow;
 39         }
 40 
 41         .active {
 42             background: #09f;
 43         }
 44 
 45         #box div,
 46         #box2 div {
 47             margin: 10px;
 48             padding: 10px;
 49             border: 1px solid #ccc;
 50         }
 51     </style>
 52     <script src="./lib/common2.js"></script>
 53     <script>
 54         window.onload = function () {
 55             var oBg = g.BgColor.Bg({
 56                 'activeClass': 'current',
 57                 'ele': 'table'
 58             });
 59             oBg.setBgColor();
 60             oBg.hover();
 61 
 62             var oBg2 = g.BgColor.Bg({
 63                 'activeClass': 'active',
 64                 'ele': 'div',
 65                 'context': '#box'
 66             });
 67             oBg2.setBgColor();
 68             oBg2.hover();
 69 
 70             var oBg3 = g.BgColor.Bg({
 71                 'activeClass': 'current',
 72                 'ele': 'div',
 73                 'evenClass': 'even-color2',
 74                 'oddClass': 'odd-color2',
 75                 'context': '#box2'
 76             });
 77             oBg3.setBgColor();
 78             oBg3.hover();
 79         }
 80     </script>
 81 </head>
 82 
 83 <body>
 84     <div id="box">
 85         <div></div>
 86         <div></div>
 87         <div></div>
 88         <div></div>
 89     </div>
 90     <div id="box2">
 91         <div></div>
 92         <div></div>
 93         <div></div>
 94         <div></div>
 95         <div></div>
 96         <div></div>
 97     </div>
 98     <table>
 99         <tr>
100             <th>姓名</th>
101             <th>性别</th>
102             <th>年龄</th>
103         </tr>
104         <tr>
105             <td>张三</td>
106             <td>man</td>
107             <td>20</td>
108         </tr>
109         <tr>
110             <td>张三</td>
111             <td>man</td>
112             <td>20</td>
113         </tr>
114         <tr>
115             <td>张三</td>
116             <td>man</td>
117             <td>20</td>
118         </tr>
119         <tr>
120             <td>张三</td>
121             <td>man</td>
122             <td>20</td>
123         </tr>
124         <tr>
125             <td>张三</td>
126             <td>man</td>
127             <td>20</td>
128         </tr>
129         <tr>
130             <td>张三</td>
131             <td>man</td>
132             <td>20</td>
133         </tr>
134         <tr>
135             <td>张三</td>
136             <td>man</td>
137             <td>20</td>
138         </tr>
139     </table>
140 </body>
141 
142 </html>
posted @ 2017-10-13 15:48  ghostwu  阅读(1693)  评论(0编辑  收藏  举报
Copyright ©2017 ghostwu