第二期:JQ编写入门(2)
在看过我们上期的技术文章之后,大家应该知道关于JQ插件的大概形式了。如果大家还没有看过我的上一期文章,可以点下面链接
第一期:JQ插件编写入门(1)
JQ插件内部的形式
; (function ($, window, document, undefined) {
/*这里定义的是私有变量,外部是访问不到的*/
var pluginName = 'yourPluginName',
defaults = {
properties: 'name'
};
/*这里定义的是私有函数,供内部调用*/
function Plugin(element, options) {
this.element = element;
this.defaults = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype={
init:function(){
//code
},
otherFunc:function(){
//code
}
};
/*这里使用了$.fn方法来拓展插件函数,当然也可以使用$.extend(),或者widget factory来达到相同的效果*/
$.fn.pluginName = function (options) {
return this.each(function () {
if (!$(this).data('plugin_' + pluginName)) {
$(this).data('plugin_' + pluginName, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
函数局部分析
私有变量
/*这里定义的是私有变量,外部是访问不到的*/
var pluginName = 'yourPluginName',
defaults = {
title: 'title',
msg: '01'
};
这里的写法,大家可以学习一下。首先我们,只用了一次Var变量声明,这样的好处是,不需要多次进行声明,每个变量定义后,用逗号隔开,最后再以一个分号结尾。其中我们把插件名字pluginName存放在一个变量里面,这样的好处是,我们浏览这个函数的开头,就直接知道这个插件的调用函数名字,而不需要拉到底部的$.fn.pluginName去查看。虽然直接在那儿命名一点错也没有。但是大家要知道,往往我们开发,是需要接手别人的项目,那么当一个插件,写了几百行的代码,如果没有清晰的结构,当别人接手我们项目维护时候,会很耗精力。
然后我们又声明了一个私有变量defaults,这个变量的作用是用来设置我们插件的默认值。为什么这个地方要使用对象来存储我们的默认参数。我们都遇到过一个情况:
function Example(num,string){
}
我们常用的传参是一个个往里面传,那么这个时候我们是要注意参数的顺序的,当我们参数很多时候,我们不得不头疼地记住每一个参数的顺序:
function Example(num,string,obj,date,reg){
}
var ex=new Example(num, , , ,reg);
这样子穿参数,就很不方便。所以我们就把参数放到一个对象里面,这样子,我们又可以不用注意参数的顺序,又可以让代码结构更加清晰。我们传参数,就直接写对象的变量名字就好了。
var data={
num:'',
string:'',
obj:'',
date:'',
reg:''
}
function Example(data){
//
}
私有方法
/*这里定义的是私有函数,供内部调用*/
function Plugin(element, options) {
this.element = element;
this.defaults = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype={
init:function(){
//code
},
otherFunc:function(){
//code
}
};
/*插件代码后段的实例化
*组合起来看
* new Plugin(this, options)
*/
这里我们用了设计模式,具体关于设计模式我们就不展开去讲。首先我们定义了一个叫Plugin的function,我们在里面用this定义静态变量和方法。
this.defaults = $.extend({}, defaults, options);
这段代码的意思的是,把传入的参数(就是用户的自定义参数)与我们的默认值(默认参数值)合并到一个对象里面,同时不会修改defaults和options的值。
$.extend(defaults,options)
这样子使用,那么我们options的参数会合并到defaults里面,defaults的默认值就被修改了。但很多时候,我们不希望defaults被修改,所以才用第一种方法。
$.extend(true/false,{},defaults,options)
这个方法的第一个参数是可选的,true代表深克隆,false代表浅克隆,就是true的时候,会递归到数组或者对象深处去合并。通常这个方法用在数组或者对象上,如果只是一般的数据类型,我们有一种很简单的方法实现默认值和自定义值的选择。
var newString = string || '';
var newNum = num ? num : 123;
当我们不需要处理数组或者对象时候,我们就可以用上面两种写法,第一种是有字符串string时候取string,没有则取字符串为空;第二种是有数字num时候取num,没有则取一个默认值数字123.
this.init();
初始化原型方法,当我们实例化这个函数时候,原型函数就执行
Plugin.prototype = {
init: function () {
//
},
otherFuc: function () {
//
}
}
这里我们把函数的方法写到原型里面,当我们实例化的时候,就不需要每次new都把方法都复制一遍。所以,每个Plugin的实例,用的方法都是调用原型里面的,这样可以较好地提升性能。
JQ插件拓展方法
/*这里使用了$.fn方法来拓展插件函数,当然也可以使用$.extend(),或者widget factory来达到相同的效果*/
$.fn.pluginName = function (options) {
return this.each(function () {
if (!$(this).data('plugin_' + pluginName)) {
$(this).data('plugin_' + pluginName, new Plugin(this, options));
}
});
};
终于到了我们插件拓展的写法了。当我们去看jq源代码的时候,其实:
$.fn = $.prototype;
其实我们这种写法就是在jQuery的原型去拓展一个方法。所以我们在平时使用的时候,就可以用$.pluginName的形式去调用方法。
return ...
为什么这里要return呢,因为当我们返回这个方法,我们可以对它链式调用。例如,$.pluginName1().pluginName2();
return this.each(function(){
//
});
这里的this,指的是$。在$.fn里面,this是指向jQuery对象。但是在this.each(function(){})里的this,指的是function的每层循环的上下文,如果要用jQuery对象,那么就要用$
return this.each(function () {
if (!$(this).data('plugin_' + pluginName)) {
$(this).data('plugin_' + pluginName, new Plugin(this, options));
}
});
在这个函数里面,我们用if先判断有没有这个插件方法,如果没有,我们就new一个实例,然后数据存储到这个插件里面。在这里我们用到$.data()方法。这个方法简单点说,就是数据缓存到某个元素上面。当我们不带参数的时候,我们就是读取;带参数,就是键值对的设置。
<p></p>
$("p").data(); //undefined
$("p").data("a","hello"); //a=="hello"
$("p").data("b",{first:1,second:"abc"});
$("p").data("b").first; //1
用法大概类似如此。
这期介绍了插件的写法,那么下期,和大家分享一下自己写的几个插件实例。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。