一.插件的种类:
- 封装对象方法的插件
- 封装全局函数的方法
- 选择器插件
二.jQuery插件的机制
jQuery提供了两个用于扩展jQuery功能方法,即jQuery.fn.extend()方法和jQuery.extend()方法。前者用于扩展前面提到的3种类型插件中的第一种,后者用于扩展后两种插件。这两个方法都接受一个参数,类型为Object。Object对象的“名/值对”分别代表“函数或方法名/函数主题”。
其中jQuery.extend()方法除了可以用于扩展jQuery对象之外,还有一个强大的功能,就是扩展已有的Object对象.
- jQuery.extend(target,obj1,...[objN])
用一个或多个对象来扩展一个对象,然后返回被扩展的对象。
例如:
- var settings={validate:false,limit:5,name:"foo"};
- var options={validate:true,name:"bar"};
- var newOptions=$.extend(settings,options);
结果为
newOptions = {validate:true,limit:5,name:"bar"}
jQuery.extend()方法经常被用来设置插件方法的一系列默认参数,例如下面的代码
- function foo(options){
- var options = $.extend({
- name:"bar",
- length:5,
- dataType:"xml"
- },otpions);
- }
- foo({name:"zzg"});
三.编写jQuery插件
1.封装jQuery对象方法的插件
编写设置和获取颜色的插件。功能和要求:
(1)设置匹配元素的颜色
(2)获取匹配元素(元素集合中的第一个)的颜色
- ;(function($){
- $.fn.extend({
- color:function(value){
- return this.css("color",value);
- }
- });
- })(jQuery)
使用:
- $(function(){
- alert($("div").color());
- alert($("div").color("red"));
- });
其实就这么简单。
下面来一个完整一点的例子:
表格隔行变色的插件
- ;(function($){
- $.fn.extend({
- "alterBgColor":function(options){
- options = $.extend({
- odd:"odd",
- even:"even",
- selected:"selected"
- },options);
- $("tbody>tr:odd",this).addClass(options.odd);
- $("tbody>tr:even",this).addClass(options.even);
- $(‘tbody>tr‘,this).click(function(){
- var hasSelect = $(this).hasClass(options.selected);
- $(this)[hasSelect?"removeClass":"addClass"](options.selected).find(‘:checkbox‘).attr(‘checked‘,!hasSelect);
- });
- $(‘tbody>tr:has(:checked)‘,this).addClass(options.selected);
- return this;
- },
- color:function(value){
- return this.css("color",value);
- }
- });
- })(jQuery)
完整代码:
- <html>
- <head>
- <style type="text/css">
- table { border:0;border-collapse:collapse;}
- td { font:normal 12px/17px Arial;padding:2px;width:100px;}
- th { font:bold 12px/17px Arial;text-align:left;padding:4px;border-bottom:1px solid #333;}
- .even { background:#FFF38F;} /* 偶数行样式*/
- .odd { background:#FFFFEE;} /* 奇数行样式*/
- .selected { background:#FF6500;color:#fff;}
- </style>
- <script src="jquery.js" type="text/javascript"></script>
- <script>
- ;(function($){
- $.fn.extend({
- "alterBgColor":function(options){
- options = $.extend({
- odd:"odd",
- even:"even",
- selected:"selected"
- },options);
- $("tbody>tr:odd",this).addClass(options.odd);
- $("tbody>tr:even",this).addClass(options.even);
- $(‘tbody>tr‘,this).click(function(){
- var hasSelect = $(this).hasClass(options.selected);
- $(this)[hasSelect?"removeClass":"addClass"](options.selected).find(‘:checkbox‘).attr(‘checked‘,!hasSelect);
- });
- $(‘tbody>tr:has(:checked)‘,this).addClass(options.selected);
- return this;
- },
- color:function(value){
- return this.css("color",value);
- }
- });
- })(jQuery)
- $(function(){
- $("#table2").alterBgColor().find("th").color("color");
- })
- </script>
- <head>
- <body>
- <table id="table1">
- <thead><tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr></thead>
- <tbody>
- <tr>
- <td><input type="checkbox" name="choice" value=""/></td>
- <td>张山</td>
- <td>男</td>
- <td>浙江宁波</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" /></td>
- <td>李四</td>
- <td>女</td>
- <td>浙江杭州</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" checked="checked" /></td>
- <td>王五</td>
- <td>男</td>
- <td>湖南长沙</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" /></td>
- <td>找六</td>
- <td>男</td>
- <td>浙江温州</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" /></td>
- <td>Rain</td>
- <td>男</td>
- <td>浙江杭州</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" checked="checked" /></td>
- <td>MAXMAN</td>
- <td>女</td>
- <td>浙江杭州</td>
- </tr>
- </tbody>
- </table>
- <br /><br />
- <table id="table2">
- <thead><tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr></thead>
- <tbody>
- <tr>
- <td><input type="checkbox" name="choice" value=""/></td>
- <td>张山</td>
- <td>男</td>
- <td>浙江宁波</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" /></td>
- <td>李四</td>
- <td>女</td>
- <td>浙江杭州</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" checked="checked" /></td>
- <td>王五</td>
- <td>男</td>
- <td>湖南长沙</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" /></td>
- <td>找六</td>
- <td>男</td>
- <td>浙江温州</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" /></td>
- <td>Rain</td>
- <td>男</td>
- <td>浙江杭州</td>
- </tr>
- <tr>
- <td><input type="checkbox" name="choice" value="" checked="checked" /></td>
- <td>MAXMAN</td>
- <td>女</td>
- <td>浙江杭州</td>
- </tr>
- </tbody>
- </table>
- </body>
- </html>
2.封装全局函数的插件
这类插件是在jQuery命名空间内部添加一个函数,例如编写一个除去左侧和右侧空格的插件
- ;(function($){
- $.extend({
- ltrim:function(text){
- return (text||"").replace(/^\s+/g,"");
- },
- rtrim:function(text){
- return (text||"").replace(/\s+$/g,"");
- }
- })
- })(jQuery);
注意:(text||"")部分是用于防止传递进来的text这个字符串变量处于未定义之类的特殊状态,如果text是undefined,则返回字符串"",否则返回字符串text。这个处理是为了保证接下来的字符串替换方法replace()方法不会出错。
使用:
- $.ltrim(" test ");
- $.rtrim(" test ");
3.自定义选择器
jQuery提供了一套方法让用户可以通过制作选择器插件来使用自定义选择器,从而使jQuery选择器功能更加完善。
jQuery的选择符解释器首先会使用一组正则表达式来解析选择器,然后针对解析出的每个选择符执行一个函数,成为选择器函数,最后根据这个选择器函数的返回值为true还是false来决定是否保留这个元素。
例如:
- $("div:gt(1)")
该选择器首先会获取所有的div元素,然后隐式遍历这些div元素,并逐个将这些div元素作为参数,连同括号里“1”等一些参数一起传递给gt对应的选择器函数进行判断
:gt()选择器在jQuery源文件中的代码如下:
- gt:function(a,i,m){
- return i>m[3]-0;
- }
其中,选择器函数一共接受3个参数:
function(a,i,m){
//...
}
第一个参数a:指向的是当前遍历到的DOM元素
第二个参数i:指的是当前遍历到的DOM元素的索引值,从0开始
第三个阐述m最为特别,它是由jQuery正则解析引擎解析后的产物,是一个数组。
- m[0],以上面的$("div:gt(1)")这个例子来讲,是:gt(1)这部分。它是jQuery选择器进一步将要匹配的内容。
- m[1],这里是选择器的引导符,匹配例子中":",即冒号。并非只能使用“:”后面跟上选择器,用户还可以自定义其他的选择引导符。
- m[2],即例子中gt,确定究竟是调用哪个选择器函数。
- m[3],即例子中的“1”,它非常有用,是编写选择器函数最重要的一个参数。
- m[4],上面的例子没有体现出来。例如"div:l(ss(dd))"这样的一个选择器中,m[4]就指向了(dd)这部分,注意是带括号的(dd),而不只是dd。同事要注意,m[3]的值是ss(dd)而非ss。
下面是一个自定义选择器的一个简单的例子
- ;(function($){
- $.extend($.expr[":"],{
- between:function(a,i,m){
- var tem = m[3].split(",");
- return tem[0]-0<i && i<tem[1]-0;
- }
- });
- })(jQuery);
注意:这里再次利用jQuery.extend()方法来对jQuery对象的一部分进行扩展。咱们自定义的选择器仅仅是jQuery.expr[":"]对象的一部分,同时也是一个Object对象。
插件使用:
- $(function(){
- $("div:between(1,4)").css("background","white");
- });
最后说一下编写插件的基本要点:
- jQuery插件的文件名推荐命名为jquery.[插件名].js,以免和其他js库插件混淆。例如命名为jquery.color.js。
- 所有的对象方法都应当附加到jQuery.fn对象上,而所有的全局函数都应当附加到jQuery对象本身上。
- 在插件内部,this指向的是当前通过选择器获取的jQuery对象,而不像一般的方法那样,例如click()方法,内部的this指向的是dom元素。
- 可以通过this.each来遍历所有的元素
- 所有的方法或函数插件,都应当以分号结尾,否则压缩的时候可能出现问题。为了更稳妥些,甚至可以在插件头部先加上一个分号,以免他人不规范代码给插件带来影响。
- 插件应当返回一个jQuery对象,以保证插件的可链式操作。除非插件返回的是一些需要获取的值,例如字符串或者数组等。
- 避免在插件内部使用$作为jQuery对象的别名,而应使用完整的jQuery来表示。这样可以避免冲突。当然,也可以利用闭包这种技巧来回避这个问题,使插件内部继续使用$作为jQuery的别名。