你的位置:首页 > Java教程

[Java教程][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' : document23   }; //存储默认配置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>