一、分类
jQuery插件主要分为3种:
①封装对象方法的插件
这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,是最常用的一种插件
②封装全局函数的插件
将独立的函数加到jQuery命名空间之下。
③选择器插件
二、基本要点
①jQuery插件的文件名推荐命名为jquery.[插件名].js,以免和其他javascript库插件混淆,例如:jquery.color.js
②所有的对象方法都应当附加到jQuery.fn对象上,而所有的全局函数都应当附加到jQuery对象本身上。
③在插件内部,this指向的是当前通过选择器获取的jQuery对象,而不像一般的方法那样,例如click()方法,内部的this指向的是DOM元素。
④可以通过this.eacj来遍历所有元素。
⑤所有的方法或函数插件,都应当以分号结尾,否则压缩的时候可能出现问题。为了更稳妥些,甚至可以在插件头部先加上一个分号,以免他人的不规范代码给插件带来影响。
⑥插件应该返回一个jQuery对象,以保证插件的可链式操作。除非插件需要返回的是一些需要获取的量,例如字符串或者数组。
⑦避免在插件内部使用$作为jQuery对象的别名,而应使用完整的jQuery来表示。这样可以避免冲突。当然也可以利用闭包来回避这个问题,使插件内部继续使用$作为jQuery的别名
三、插件中的闭包
关于闭包:允许使用内部函数(即函数定义和函数表达式位于另一个函数的函数体内),而且这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数,当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。即内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必须访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会收到函数内部函数的影响。
利用闭包的特性,既可以避免内部临时变量影响全局空间,又可以在插件内部继续使用$作为jQuery别名。
常见的jQuery插件形式:
(function() {
/*这里放置代码*/
})();
首先定义一个匿名函数function(){/*这里放置代码*/},然后用括号括起来,变成(funcion(){/*这里放置代码*/})这种形式,最后通过()这个运算符来执行。可以传递参数进去,以供内部函数使用。
常见的jQuery插件的结构
//注意为了更好的兼容性,开始前有个分号
;(function($) { //此处将$作为匿名函数的形参
/*这里放置代码,可以使用$作为jQuery的缩写别名*/
})(jQuery); //这里将jQuery作为实参传递给匿名函数
四、插件的机制
1、jQuery提供了两个用于拓展jQuery功能的方法,即jQuery.fn.extend()方法和jQuery.extend()方法。
①jQuery.fn.extend()方法用于封装对象方法的插件。
②jQuery.extend()方法用于封装全局函数的插件和选择器插件。
2、两种方法都接收一个object参数。object对象的“名/值对”分别代表“函数或方法名/函数主体”。
3、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=jQuery.extend(settings,options);
结果:
newOptions={validate:true,limit:5,name:”foo”};
②jQuery.extend()方法经常被用于设置插件方法的一系列默认参数
options = jQuery.extend({
name: "bar",
length: 5,
dataType: "xml"
}, options); /*options为传递的参数*/
如果用户调用foo()方法的时候,在传递的参数options对象设置了相应的值,那么就使用设置的值,否则使用默认值。
五、编写插件
1、封装jQuery对象方法的插件
①color()插件:jquery.color.js
//注意为了更好的兼容性,开始前有个分号
;(function($) { //此处将$作为匿名函数的形参
/*这里放置代码,可以使用$作为jQuery的缩写别名*/
$.fn.extend({
"color": function(value) {
if (value == undefined) {
return this.css("color");
} else {
return this.css("color", value);
}
}
})
})(jQuery); //这里将jQuery作为实参传递给匿名函数
②表格隔行变色插件:jquery.alertBgColor.js
;(function($) {
$.fn.extend({
"alertBgColor": function(options) {
options = $.extend({
odd: "odd",
even: "even",
selected: "selected"
}, options);
}$("tbody>tr:odd", this).addClass(options.add);
$("tbody>tr:even", this).addClass(options.even);
$("tbody>tr", this).click(function() {
//判断当前是否选中
var hasSelected = $(this).hasClass(options.selected);
//如果选中,则移出selected类,否则加上selected类
$(this)[hasSelected ? "removeClass" : "addClass"](
options.selected)
//查找内部的checkbox,设置对应的属性
.find(':checked').attr('checked', !hasSelected);
});
//如果单选框默认情况下是选择的,则高色
$("tbody>tr:has(:checked)", this).addClass(options,
selected);
return this; //返回this,使方法可链
});
})(jQuery);
2、封装全局函数的插件
这类插件是在jQuery命名空间内部添加一个函数。
去除左右空格:jquery.trim.js
;(function($){
$.extend({
ltrim:function(text){
return (text||"").replace(/^\s+/g,"");
},
rtrim:function(text){
return (text||"").replace('',/^\s);
}
});
})(jQuery);
3、自定义选择器
between选择器:
;$(function($) {
$.extend($.expr[":"], {//选择器是jQuery.expr[“:”]对象的一部分,同时也是一个object对象,因此可以直接利用jQuery.extend()对其进行扩展
between: function(a, i, m) {
var tmp = m[3].split(",");
return tmp[0] - 0 < i && i < tmp[1] - 0;
}
});
})(jQuery);
插件应用:
$(“function”(){
$(“div.between(2,5)”)…
});
选择器的函数一共接受3个参数
function(a,i,m){ //……. }
第一个参数a:指向的是当前遍历的DOM元素
第二个参数i:指的是当前遍历到的DOM元素的索引值,从0开始
第三个参数m:由jQuery正则解析引擎进一步解析后的产物(由match匹配出来的),是一个数组
①m[0],以上面的$(“div.between(2,5)”)例子为例,是:between(2,5)这部分,是jQuery选择器进一步将要匹配的内容
②m[1],这里是选择器的引导负,匹配例子中的“:”,即冒号。并非只能使用“:”,后面跟上选择器,用户还可以自定义其他的选择器引导符
③m[2],即例子中的between,确定究竟是调用那个选择器函数
④m[3],即例子中括号里的数字“2,5”,它非常有用,是编写选择器函数最重要的一个参数
⑤m[4],上面例子没有体现出来,出现比较罕见。例如“div:l(ss(dd))”这样一个选择器,m[4]就指向了(dd)这部分,注意是带括号的(dd),而不只是dd。同时要注意,此时的m[3]的值是ss(dd)而非ss