jquery插件开发大概有三种方式: 1,$.extend()-在jquery命名空间即jquery本身上添加静态方法;调用,例如:$.myPlugin();而非$('ele').myPlugin(); 2,$.fn.extend()-
3,$.widget()-
$.extend({
createNum:function(name){
return 'hello '+(name?name:'andy');
}
});
console.log($.createNum());//hello andy
console.log($.createNum('jack'));// hello jack
html:
刘德华
张学友
黎明
郭富城
以上代码通过$.extend()方法想jquery添加的,直接通过$调用; 但是,发现这种扩展方式无法通过DOM选择器来触发,这个时候我们就需要考虑$.fn.extend()的扩展方式了; 如下,基本格式:
$.fn.sayHello= function(){
// to do
};
/*
现在我们将页面中的字改变颜色
* */
$.fn.changeColor = function(){
this.css('color','red');// this 即选中的元素;当前指$('p')
};
// 调用如下:
$('#ex-div p').changeColor();
当然,其实在插件代码里我们经常处理某个具体的元素,而不是一个元素的集合
上面的代码,this指的是jquery选择器返回的集合,我们可以通过jquery中的$.each()方法处理集合中的每个元素了;
但是,在each方法内部,this指代的就是普通的DOM元素了,如果需要调用jquery的方法那就需要用$来重新包装一下;
现在我们来处理,在每个p标签里面加上一个i标签,内容为-香港
$.fn.changeConts = function(){
//这里对this是用jquery选中的元素\
var _html = '-香港'
this.css('color','red');
this.each(function(){
//对每个元素进行操作
$(this).append(_html);
});
};
$('#ex-div p').changeConts();
我们又丰富了插件,接下来我们继续接受参数的延伸 为了让插件支持链式调用,我们需要return一下;
$.fn.changeConts = function(){
//这里对this是用jquery选中的元素\
var _html = '-香港'
this.css('color','red');
return this.each(function(){
//对每个元素进行操作
$(this).append(_html);
});
};
$('#ex-div').css('border','1px solid red').find('p').changeConts();
接下来,我们就处理参数的部分; 比如现在我们处理字体的颜色,由用户来定义颜色,如果用户没有定义,我们就取默认值 说明一点: 在处理插件参数的接收上,通常使用jquery的extend方法,上面也提及过,但那是给extend方法传递单个对象的情况下, 这个对象会合并到jquery身上,所以我们就可以在jquery身上调用新合并对象里包含的方法了,如上面的例子; 当给extend方法传递一个以上的参数时,它会将所有到参数对象合并到第一个里. 同时,如果对象中有同名的属性,合并后后面的参数会覆盖前面的; 利用这一点,我们可以在插件里定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上, 最后便实现了用户指定参数使用的值,未指定的参数使用默认值; 我们定义下font-size,允许插件调用的时候设置字体;
$.fn.extend({
changeConts: function (options) {
var defaults = {
'color':'red',
'fontSize':'12px'
};
var setting = $.extend(defaults,options);
return this.css({
'color':setting.color,
'fontSize':setting.fontSize
});
}
});
//未指定字体大小的时候,默认值为12px
$('#ex-div p').changeConts({
'color':'blue'
});
//我们来指定字体大小
$('#ex-div p').changeConts({
'color':'red',
'fontSize':'20px'
});
虽然实现了参数的传递,但是我们没有保护包参数
我们可以看到调用extend时,会将defaults的值改变,这样不是我们期望的,我们希望它维持原样,方便其它调用; 一个好的做法是,将一个新的空对象作为$.extend的第一个参数,defaults和用户传递的参数紧跟其后, 这样做的好处就是所有值都合并到这个空对象上,保护了插件里面到默认值;
$.fn.extend({
changeConts:function(options){
var defaults = {
'color':'red',
'fontSize':'12px'
};
var setting = $.extend({},defaults,options);
return this.css({
'color':setting.color,
'fontSize':setting.fontSize
});
}
});
$('#ex-div p').changeConts({
'color':'blue',
'fontSize':'20px'
});
至此,插件可以接受参数和处理参数后,就可以愉快的编写插件了; 若要编写一个庞大的优雅的插件,我们需要将插件包装到一个对象上,用面向对象的思维进行开发; 如果将需要的重要变量定义到对象的属性上,函数变成对象的方法,当我们需要的时候通过对象获取, 一来方便管理,二来不会影响外部命名空间,因为这些所有的变量名和方法名都是在对象内部; 接下来,我们来优化代码
// 定义Slipactive的构造函数;
function Slipactive(ele,opt){
this.$element = ele;
this.dafaults = {
'color':'red',
'fontSize':'12px',
'textDecoration':'none'
};
this.options = $.extend({},this.dafaults,opt)
}
Slipactive.prototype = {
constructor:Slipactive,
slipactive:function(){
this.$element.css({
'color':this.options.color,
'fontSize':this.options.fontSize,
'textDecoration':this.options.textDecoration
});
return this;
}
};
// 在插件中使用Slipactive对象
$.fn.extend({
mySlipa:function(options){
// 创建Slipactive
var slipactive = new Slipactive(this,options);
// 调用方法
return slipactive.slipactive();
}
});
$('#ex-div p').mySlipa({
'color':'blue',
'fontSize':'30px'
});
以上便是面向对象,也更好维护和理解,以后要添加新方法,只需向对象添加新变量和方法就行, 然后便可以在插件实例化后即可调用新添加的东西
$('#ex-div p').mySlipa({
'color':'blue',
'fontSize':'30px',
'textDecoration':'underline'
});
至此,插件开发已经完毕; 接下来,我们来做些锦上添花的东西;例如优化命名空间,变量等 其实,我们在写js的时候就应该不要污染全局变量;我们可以采用闭包包裹代码
(function(){
function Slipactive(ele,opt){
this.$element = ele;
this.dafaults = {
'color':'red',
'fontSize':'12px',
'textDecoration':'none'
};
this.options = $.extend({},this.dafaults,opt)
}
Slipactive.prototype = {
constructor:Slipactive,
slipactive:function(){
this.$element.css({
'color':this.options.color,
'fontSize':this.options.fontSize,
'textDecoration':this.options.textDecoration
});
return this;
}
};
// 在插件中使用Slipactive对象
$.fn.extend({
mySlipa:function(options){
// 创建Slipactive
var slipactive = new Slipactive(this,options);
// 调用方法
return slipactive.slipactive();
}
});
})();
自调用匿名函数里面的代码会在第一时间执行;
然后,将系统变量以参数形式传递到插件内部也是个不错的实践;
这样,window等系统变量在插件内部就有了一个局部的引用,可以提高访问效率;
结构如下:
;(function($,window,document,undefiend){
// to do
})(jQuery,window,document);
最后解释下undefiend
为了得到没有被修改的undefiend,我们并没有传递这个参数,但是却在接收的时候接收了它,
因为实际上并没有传,所以'undefiend'那个位置接收到的就是真正的undefiend了;
至此,完毕!