在看過咱們上期的技術文章以後,你們應該知道關於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
用法大概相似如此。
這期介紹了插件的寫法,那麼下期,和你們分享一下本身寫的幾個插件實例。