在看过咱们上期的技术文章以后,你们应该知道关于JQ插件的大概形式了。若是你们尚未看过个人上一期文章,能够点下面连接
第一期:JQ插件编写入门(1)segmentfault
; (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被修改,因此才用第一种方法。this
$.extend(true/false,{},defaults,options)
这个方法的第一个参数是可选的,true表明深克隆,false表明浅克隆,就是true的时候,会递归到数组或者对象深处去合并。一般这个方法用在数组或者对象上,若是只是通常的数据类型,咱们有一种很简单的方法实现默认值和自定义值的选择。prototype
var newString = string || ''; var newNum = num ? num : 123;
当咱们不须要处理数组或者对象时候,咱们就能够用上面两种写法,第一种是有字符串string时候取string,没有则取字符串为空;第二种是有数字num时候取num,没有则取一个默认值数字123.插件
this.init();
初始化原型方法,当咱们实例化这个函数时候,原型函数就执行
Plugin.prototype = { init: function () { // }, otherFuc: function () { // } }
这里咱们把函数的方法写到原型里面,当咱们实例化的时候,就不须要每次new都把方法都复制一遍。因此,每一个Plugin的实例,用的方法都是调用原型里面的,这样能够较好地提高性能。
/*这里使用了$.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
用法大概相似如此。
这期介绍了插件的写法,那么下期,和你们分享一下本身写的几个插件实例。