jQuery插件的開發包括兩種:
1、類級別的插件開發
1.1 添加一個新的全局函數
添加一個全局函數,我們只需如下定義:
1 2 3 | jQuery.foo = function () { alert( 'This is a test. This is only a test.' ); }; |
1.2 增加多個全局函數
添加多個全局函數,可採用如下定義:
1 2 3 4 5 6 7 | jQuery.foo = function () { alert( 'This is a test. This is only a test.' ); }; jQuery.bar = function (param) { alert( 'This function takes a parameter, which is "' + param + '".' ); }; 調用時和一個函數的一樣的:jQuery.foo();jQuery.bar();或者$.foo();$.bar( 'bar' ); |
1.3 使用jQuery.extend(object);
1 2 3 4 5 6 7 8 | jQuery.extend({ foo: function () { alert( 'This is a test. This is only a test.' ); }, bar: function (param) { alert( 'This function takes a parameter, which is "' + param + '".' ); } }); |
1.4 使用命名空間
雖然在jQuery命名空間中,我們禁止使用了大量的javaScript函數名和變量名。但是仍然不可避免某些函數或變量名將於其他jQuery插件衝突,因此我們習慣將一些方法封裝到另一個自定義的命名空間。
1 2 3 4 5 6 7 8 9 10 11 | jQuery.myPlugin = { foo: function () { alert( 'This is a test. This is only a test.' ); }, bar: function (param) { alert( 'This function takes a parameter, which is "' + param + '".' ); } }; 採用命名空間的函數仍然是全局函數,調用時採用的方法: $.myPlugin.foo(); $.myPlugin.bar( 'baz' ); |
通過這個技巧(使用獨立的插件名),我們可以避免命名空間內函數的衝突。
2、對象級別的插件開發
對象級別的插件開發需要如下的兩種形式:
形式1:
1 2 3 4 5 6 7 | ( function ($){ $.fn.extend({ pluginName: function (opt,callback){ // Our plugin implementation code goes here. } }) })(jQuery); |
形式2:
1 2 3 4 5 | ( function ($) { $.fn.pluginName = function () { // Our plugin implementation code goes here. }; })(jQuery); |
上面定義了一個jQuery函數,形參是$,函數定義完成之後,把jQuery這個實參傳遞進去.立即調用執行。這樣的好處是,我們在寫jQuery插件時,也可以使用$這個別名,而不會與prototype引起衝突。
這是一個單一插件的腳本。如果你的腳本中包含多個插件,或者互逆的插件(例如: $.fn.doSomething() 和 $.fn.undoSomething()),那麼你需要聲明多個函數名字。但是,通常當我們編寫一個插件時,力求僅使用一個名字來包含它的所有內容。我們的示例插件命名爲“highlight“
1 2 3 4 5 | $.fn.hilight = function () { // Our plugin implementation code goes here. }; 我們的插件通過這樣被調用: $( '#myDiv' ).hilight(); |
但是如果我們需要分解我們的實現代碼爲多個函數該怎麼辦?有很多原因:設計上的需要;這樣做更容易或更易讀的實現;而且這樣更符合面向對象。 這真是一個麻煩事,把功能實現分解成多個函數而不增加多餘的命名空間。出於認識到和利用函數是javascript中最基本的類對象,我們可以這樣做。就像其他對象一樣,函數可以被指定爲屬性。因此我們已經聲明“hilight”爲jQuery的屬性對象,任何其他的屬性或者函數我們需要暴露出來的,都可以在"hilight" 函數中被聲明屬性。稍後繼續。
2.2 接受options參數以控制插件的行爲讓我們爲我們的插件添加功能指定前景色和背景色的功能。我們也許會讓選項像一個options對象傳遞給插件函數。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // plugin definition $.fn.hilight = function (options) { var defaults = { foreground: 'red' , background: 'yellow' }; // Extend our default options with those provided. var opts = $.extend(defaults, options); // Our plugin implementation code goes here. }; 我們的插件可以這樣被調用: $( '#myDiv' ).hilight({ foreground: 'blue' }); |
我們應該對上面代碼的一種改進是暴露插件的默認設置。這對於讓插件的使用者更容易用較少的代碼覆蓋和修改插件。接下來我們開始利用函數對象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // plugin definition $.fn.hilight = function (options) { // Extend our default options with those provided. // Note that the first arg to extend is an empty object - // this is to keep from overriding our "defaults" object. var opts = $.extend({}, $.fn.hilight.defaults, options); // Our plugin implementation code goes here. }; // plugin defaults - added as a property on our plugin function $.fn.hilight.defaults = { foreground: 'red' , background: 'yellow' }; 現在使用者可以包含像這樣的一行在他們的腳本里: //這個只需要調用一次,且不一定要在ready塊中調用 $.fn.hilight.defaults.foreground = 'blue' ; 接下來我們可以像這樣使用插件的方法,結果它設置藍色的前景色: $( '#myDiv' ).hilight(); |
1 2 3 4 5 6 7 8 9 10 | // 覆蓋插件缺省的背景顏色 $.fn.hilight.defaults.foreground = 'blue' ; // ... // 使用一個新的缺省設置調用插件 $( '.hilightDiv' ).hilight(); // ... // 通過傳遞配置參數給插件方法來覆蓋缺省設置 $( '#green' ).hilight({ foreground: 'green' }); |
這段將會一步一步對前面那段代碼通過有意思的方法擴展你的插件(同時讓其他人擴展你的插件)。例如,我們插件的實現裏面可以定義一個名叫"format"的函數來格式化高亮文本。我們的插件現在看起來像這樣,默認的format方法的實現部分在hiligth函數下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // plugin definition $.fn.hilight = function (options) { // iterate and reformat each matched element return this .each( function () { var $ this = $( this ); // ... var markup = $ this .html(); // call our format function markup = $.fn.hilight.format(markup); $ this .html(markup); }); }; // define our format function $.fn.hilight.format = function (txt) { return '<strong>' + txt + '</strong>' ; }; |
考慮到這個篇文章中我們建立的無用的插件,你也許想知道究竟什麼時候這些會有用。一個真實的例子是Cycle插件.這個Cycle插件是一個滑動顯示插件,他能支持許多內部變換作用到滾動,滑動,漸變消失等。但是實際上,沒有辦法定義也許會應用到滑動變化上每種類型的效果。那是這種擴展性有用的地方。 Cycle插件對使用者暴露"transitions"對象,使他們添加自己變換定義。插件中定義就像這樣:
1 2 3 | $.fn.cycle.transitions = { // ... }; |
那麼我們怎麼定義更多的函數而不攪亂命名空間也不暴露實現呢?這就是閉包的功能。爲了演示,我們將會添加另外一個“debug”函數到我們的插件中。這個 debug函數將爲輸出被選中的元素格式到firebug控制檯。爲了創建一個閉包,我們將包裝整個插件定義在一個函數中。
1 2 3 4 5 6 7 8 9 10 11 12 13 | ( function ($) { // plugin definition $.fn.hilight = function (options) { debug( this ); // ... }; // private function for debugging function debug($obj) { if (window.console && window.console.log) window.console.log( 'hilight selection count: ' + $obj.size()); }; // ... })(jQuery); |
在你正在寫的插件的基礎上,添加對Metadata插件的支持能使他更強大。個人來說,我喜歡這個Metadata插件,因爲它讓你使用不多的"markup”覆蓋插件的選項(這非常有用當創建例子時)。而且支持它非常簡單。更新:註釋中有一點優化建議。
1 2 3 4 5 6 7 8 9 | $.fn.hilight = function (options) { // ... // build main options before element iteration var opts = $.extend({}, $.fn.hilight.defaults, options); return this .each( function () { var $ this = $( this ); // build element specific options var o = $.meta ? $.extend({}, opts, $ this .data()) : opts; //... |
調用的時候可以這樣寫: jQuery.foo(); 或 $.foo();
1 2 3 4 5 6 7 8 9 10 11 | <div .= "hilight { background: 'red', foreground: 'white' }" > Have a nice day! </div> <div .= "hilight { foreground: 'orange' }" > Have a nice day! </div> <div .= "hilight { background: 'green' }" > Have a nice day! </div> 現在我們能高亮哪些div僅使用一行腳本: $( '.hilight' ).hilight(); |
2.7 整合
下面使我們的例子完成後的代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // 創建一個閉包 ( function ($) { // 插件的定義 $.fn.hilight = function (options) { debug( this ); // build main options before element iteration var opts = $.extend({}, $.fn.hilight.defaults, options); // iterate and reformat each matched element return this .each( function () { $ this = $( this ); // build element specific options var o = $.meta ? $.extend({}, opts, $ this .data()) : opts; // update element styles $ this .css({ backgroundColor: o.background, color: o.foreground }); var markup = $ this .html(); // call our format function markup = $.fn.hilight.format(markup); $ this .html(markup); }); }; // 私有函數:debugging function debug($obj) { if (window.console && window.console.log) window.console.log( 'hilight selection count: ' + $obj.size()); }; // 定義暴露format函數 $.fn.hilight.format = function (txt) { return '<strong>' + txt + '</strong>' ; }; // 插件的defaults $.fn.hilight.defaults = { foreground: 'red' , background: 'yellow' }; // 閉包結束 })(jQuery); |
1 2 | jQuery.fn.extend(object); 給jQuery對象添加方法。 jQuery.extend(object); 爲擴展jQuery類本身.爲類添加新的方法。 |
1 | jQuery.fn = jQuery.prototype = { init: function ( selector, context ) { //.... //...... }; |
1 2 3 | $.fn.extend({ alertWhileClick: function (){ $( this ).click( function (){ alert($( this ).val()); }); } }); $( "#input1" ).alertWhileClick(); //頁面上爲: $( "#input1" ) 爲一個jQuery實例,當它調用成員方法 alertWhileClick後,便實現了擴展,每次被點擊時它會先彈出目前編輯裏的內容。 |
1 | $.extend({ add: function (a,b){ return a+b;} }); |
便爲jQuery添加一個爲 add的“靜態方法”,之後便可以在引入 jQuery的地方,使用這個方法了,$.add(3,4); //return 7
原文:w3cfuns.com