1、jquery的插件機制:css
jQuery.extend(object) ,一個參數的用於擴展jQuery類自己,也就是用來在jQuery類/命名空間上增長新函數,或者叫靜態方法,例如jQuery內置的 ajax方法都是用jQuery.ajax()這樣調用的,有點像 「類名.方法名」 靜態方法的調用方式。下面咱們也來寫個jQuery.extend(object)的例子: 複製代碼html
//擴展jQuery對象自己 jQuery.extend({ "minValue": function (a, b) { ///<summary> /// 比較兩個值,返回最小值 ///</summary> return a < b ? a : b; }, "maxValue": function (a, b) { ///<summary> /// 比較兩個值,返回最大值 ///</summary> return a > b ? a : b; } }); //調用 var i = 100; j = 101; var min_v = $.minValue(i, j); // min_v 等於 100 var max_v = $.maxValue(i, j); // max_v 等於 101
重載版本:jQuery.extend([deep], target, object1, [objectN])jquery
用一個或多個其餘對象來擴展一個對象,返回被擴展的對象。 若是不指定target,則給jQuery命名空間自己進行擴展。這有助於插件做者爲jQuery增長新方法。 若是第一個參數設置爲true,則jQuery返回一個深層次的副本,遞歸地複製找到的任何對象。不然的話,副本會與原對象共享結構。 未定義的屬性將不會被複制,然而從對象的原型繼承的屬性將會被複制。 參數 deep: 可選。若是設爲true,則遞歸合併。 target: 待修改對象。 object1: 待合併到第一個對象的對象。 objectN: 可選。待合併到第一個對象的對象。 示例1: 合併 settings 和 options,修改並返回 settings。 var settings = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; jQuery.extend(settings, options); 結果: settings == { validate: true, limit: 5, name: "bar" }ajax
示例2: 合併 defaults 和 options, 不修改 defaults。 var empty = {}; var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; var settings = jQuery.extend(empty, defaults, options); 結果: settings == { validate: true, limit: 5, name: "bar" } empty == { validate: true, limit: 5, name: "bar" }bootstrap
這個重載的方法,咱們通常用來在編寫插件時用自定義插件參數去覆蓋插件的默認參數。閉包
jQuery.fn.extend(object)擴展 jQuery 元素集來提供新的方法(一般用來製做插件)。框架
首先咱們來看fn 是什麼東西呢。查看jQuery代碼,就不難發現。dom
jQuery.fn = jQuery.prototype = {函數
init: function( selector, context ) {.....}; };測試
原來 jQuery.fn = jQuery.prototype,也就是jQuery對象的原型。那jQuery.fn.extend()方法就是擴展jQuery對象的原型方法。咱們知道擴展原型上的方法,就至關於爲對象添加」成員方法「,類的」成員方法「要類的對象才能調用,因此使用jQuery.fn.extend(object)擴展的方法, jQuery類的實例可使用這個「成員函數」。jQuery.fn.extend(object)和jQuery.extend(object)方法必定要區分開來。
2、自執行的匿名函數/閉包:
另外, 函數轉換爲表達式的方法並不必定要靠分組操做符(),咱們還能夠用void操做符,~操做符,!操做符……
例如: bootstrap 框架中的插件寫法: !function($){ //do something; }(jQuery);
和 (function($){ //do something; })(jQuery); 是一回事。
匿名函數最大的用途是建立閉包(這是JavaScript語言的特性之一),而且還能夠構建命名空間,以減小全局變量的使用。 例如: var a=1; (function()(){ var a=100; })(); alert(a); //彈出 1
3、一步一步封裝JQuery插件
接下來咱們一塊兒來寫個高亮的jqury插件 1.定一個閉包區域,防止插件"污染"
//閉包限定命名空間 (function ($) {
})(window.jQuery);
2.jQuery.fn.extend(object)擴展jquery 方法,製做插件
//閉包限定命名空間 (function ($) { $.fn.extend({ "highLight":function(options){ //do something } }); })(window.jQuery);
3.給插件默認參數,實現 插件的功能
//閉包限定命名空間 (function ($) { $.fn.extend({ "highLight": function (options) { var opts = $.extend({}, defaluts, options); //使用jQuery.extend 覆蓋插件默認參數 this.each(function () { //這裏的this 就是 jQuery對象 //遍歷全部的要高亮的dom,當調用 highLight()插件的是一個集合的時候。 var $this = $(this); //獲取當前dom 的 jQuery對象,這裏的this是當前循環的dom //根據參數來設置 dom的樣式 $this.css({ backgroundColor: opts.background, color: opts.foreground }); });
} }); //默認參數 var defaluts = { foreground: 'red', background: 'yellow' };
})(window.jQuery);
到這一步,高亮插件基本功能已經具有了。調用代碼以下:
$(function () { $("p").highLight(); //調用自定義 高亮插件 });
這裏只能 直接調用,不能鏈式調用。咱們知道jQuey是能夠鏈式調用的,就是能夠在一個jQuery對象上調用多個方法,如: $('#id').css({marginTop:'100px'}).addAttr("title","測試「); 可是咱們上面的插件,就不能這樣鏈式調用了。好比:$("p").highLight().css({marginTop:'100px'}); //將會報找不到css方法,緣由在與個人自定義插件在完成功能後,沒有將 jQuery對象給返回出來。接下來,return jQuery對象,讓咱們的插件也支持鏈式調用。(其實很簡單,就是執行完咱們插件代碼的時候將jQuery對像return 出來,和上面的代碼沒啥區別)
1 //閉包限定命名空間 2 (function ($) { 3 $.fn.extend({ 4 "highLight": function (options) { 5 var opts = $.extend({}, defaluts, options); //使用jQuery.extend 覆蓋插件默認參數 6 return this.each(function () { //這裏的this 就是 jQuery對象。這裏return 爲了支持鏈式調用 7 //遍歷全部的要高亮的dom,當調用 highLight()插件的是一個集合的時候。 8 var $this = $(this); //獲取當前dom 的 jQuery對象,這裏的this是當前循環的dom 9 //根據參數來設置 dom的樣式 10 $this.css({ 11 backgroundColor: opts.background, 12 color: opts.foreground 13 }); 14 }); 15 16 } 17 }); 18 //默認參數 19 var defaluts = { 20 foreground: 'red', 21 background: 'yellow' 22 }; 23 })(window.jQuery);
4.暴露公共方法 給別人來擴展你的插件(若是有需求的話) 好比的高亮插件有一個format方法來格式話高亮文本,則咱們可將它寫成公共的,暴露給插件使用者,不一樣的使用着根據本身的需求來重寫該format方法,從而是高亮文本能夠呈現不一樣的格式。
//公共的格式化 方法. 默認是加粗,用戶能夠經過覆蓋該方法達到不一樣的格式化效果。 $.fn.highLight.format = function (str) { return "<strong>" + str + "</strong>"; }
5.插件私有方法 有些時候,咱們的插件須要一些私有方法,不能被外界訪問。例如 咱們插件裏面須要有個方法 來檢測用戶調用插件時傳入的參數是否符合規範。 6.其餘的一些設置,如:爲你的插件加入元數據插件的支持將使其變得更強大。
完整的高亮插件代碼以下:
//閉包限定命名空間 (function ($) { $.fn.extend({ "highLight": function (options) { //檢測用戶傳進來的參數是否合法 if (!isValid(options)) return this; var opts = $.extend({}, defaluts, options); //使用jQuery.extend 覆蓋插件默認參數 return this.each(function () { //這裏的this 就是 jQuery對象。這裏return 爲了支持鏈式調用 //遍歷全部的要高亮的dom,當調用 highLight()插件的是一個集合的時候。 var $this = $(this); //獲取當前dom 的 jQuery對象,這裏的this是當前循環的dom //根據參數來設置 dom的樣式 $this.css({ backgroundColor: opts.background, color: opts.foreground }); //格式化高亮文本 var markup = $this.html(); markup = $.fn.highLight.format(markup); $this.html(markup); });
} }); //默認參數 var defaluts = { foreground: 'red', background: 'yellow' }; //公共的格式化 方法. 默認是加粗,用戶能夠經過覆蓋該方法達到不一樣的格式化效果。 $.fn.highLight.format = function (str) { return "<strong>" + str + "</strong>"; } //私有方法,檢測參數是否合法 function isValid(options) { return !options || (options && typeof options === "object") ? true : false; }
})(window.jQuery); //調用者覆蓋 插件暴露的共公方法 $.fn.highLight.format = function (txt) { return "<em>" + txt + "</em>" } $(function () { $("p").highLight({ foreground: 'orange', background: '#ccc' }); //調用自定義 高亮插件 });