基礎
1、jQuery插件開發主要使用如下兩個方法:
1.1、添加靜態方法
jQuery.extend(object);
為擴展jQuery本身,為類添加新的方法,可以理解文添加靜態方法。
$.extend({ addMethod : function(a, b){return a + b;} // $.addMethod(1, 2); //return 3 });
1.2、添加成員方法
jQuery.fn.extend(object); jQuery.fn = jQuery.prototype
給jQuery對象添加方法,對jQuery.prototype進行擴展,為jQuery類添加成員方法:
$.fn.extend({ getInputText:function(){ $(this).click(function(){ alert($(this).val()); }); } }); $("#username").getInputText();
2、一個通用的框架:
以下是一個通用的框架:
(function($){ $.fn.yourPluginName = function(options){ //各種屬性和參數 var options = $.extend(defaults, options); this.each(function(){ //插件的實現代碼 }); }; })(jQuery);
關于
$.extend(defaults, options);
就是通過合并defaults和options來擴展defaults,實現插件默認參數的功能。
實踐
1、聲明插件名稱:
添加一個函數到jQuery.fn(jQuery.prototype)對象,該函數的名稱就是你的插件名稱:
jQuery.fn.myPlugin = function() { // Do your awesome plugin stuff here };
在命名不與jQuery其他函數沖突的情況,可以使用閉包的方式使用$符號:
(function( $ ) { $.fn.myPlugin = function() { // Do your awesome plugin stuff here }; })( jQuery );
2、插件中的上下文:
jQuery接收一個回調,該回調本身就指向了dom,直接使用this就相當于我們平時的$(this)的情況:
(function( $ ){ $.fn.myPlugin = function() { // there's no need to do $(this) because // "this" is already a jquery object // $(this) would be the same as $($('#element')); this.fadeIn('normal', function(){ // the this keyword is a DOM element }); }; })( jQuery ); $('#element').myPlugin();
下面是一個簡單的jQuery插件,實現獲取所有div的最大高度:
(function( $ ){ $.fn.maxHeight = function() { var max = 0; this.each(function() { max = Math.max( max, $(this).height() ); }); return max; }; })( jQuery ); var tallest = $('div').maxHeight(); // Returns the height of the tallest div
3、維護鏈接性:
前面的示例返回一個整數值最高的div,但是通常的意圖僅在某種程度上是僅修改插件的元素集合,并將它們傳遞到下一個鏈中的方法。這樣的jQuery的設計優雅的地方。所以保持鏈接性放到一個插件,您必須確保您的插件返回這個關鍵字。
(function( $ ){ $.fn.lockDimensions = function( type ) { return this.each(function() { var $this = $(this); if ( !type || type == 'width' ) { $this.width( $this.width() ); } if ( !type || type == 'height' ) { $this.height( $this.height() ); } }); }; })( jQuery ); $('div').lockDimensions('width').css('color', 'red');
因為插件返回this關鍵字的范圍,它維護鏈接性,jQuery可以繼續利用jQuery方法,如. css。所以,如果你的插件不返回一個內在價值,你應該總是返回this。
4、參數的傳遞,Defaults和Options:
(function( $ ){ $.fn.tooltip = function( options ) { // Create some defaults, extending them with any options that were provided var settings = $.extend( { 'location' : 'top', 'background-color' : 'blue' }, options); return this.each(function() { // Tooltip plugin code here }); }; })( jQuery ); $('div').tooltip({ 'location' : 'left' });
通過$.extend合并默認參數和調用者傳入的參數。
5、命名空間:
正確的命名空間在插件開發中是一個非常重要的部分。正確的命名空間,可以確保你的插件將有一個很低的幾率在同一個頁面上被他插件或代碼覆蓋。
在任何情況下都不應該在一個插件的jQuery.fn對象中聲稱多個名稱空間。
(function( $ ){ $.fn.tooltip = function( options ) { // THIS }; $.fn.tooltipShow = function( ) { // IS }; $.fn.tooltipHide = function( ) { // BAD }; $.fn.tooltipUpdate = function( content ) { // !!! }; })( jQuery );
你應該收集所有的方法到一個對象化字面,并且通過方法的字面值進行調用:
(function( $ ){ var methods = { init : function( options ) { // THIS }, show : function( ) { // IS }, hide : function( ) { // GOOD }, update : function( content ) { // !!! } }; $.fn.tooltip = function( method ) { // Method calling logic if ( methods[method] ) { return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.tooltip' ); } }; })( jQuery ); // calls the init method $('div').tooltip(); // calls the init method $('div').tooltip({ foo : 'bar' }); // calls the hide method $('div').tooltip('hide'); // calls the update method $('div').tooltip('update', 'This is the new tooltip content!');
這種類型的方法封裝和體系結構在jQuery插件社區中是一個標準,它適用于無數的插件,包括jQueryUI插件和小部件。
6、Events:
Bind方法允許通過命名空間的方式綁定事件,如果你的插件綁定了事件,可以通過命名空間的方式,在解除綁定事件時,你也可以這樣做,來防止影響到其他的事件??梢酝ㄟ^“.<namespace>” 的方式來設置綁定事件的命名空間。
(function( $ ){ var methods = { init : function( options ) { return this.each(function(){ $(window).bind('resize.tooltip', methods.reposition); }); }, destroy : function( ) { return this.each(function(){ $(window).unbind('.tooltip'); }) }, reposition : function( ) { // ... }, show : function( ) { // ... }, hide : function( ) { // ... }, update : function( content ) { // ... } }; $.fn.tooltip = function( method ) { if ( methods[method] ) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.tooltip' ); } }; })( jQuery ); $('#fun').tooltip(); // Some time later... $('#fun').tooltip('destroy');
7、Data:
關于data方法可以參考官方的文檔:http://docs.jquery.com/Data,既是在頁面的元素中綁定存儲數據。
這里通過編寫插件,實現在頁面中的每個元素都綁定一些當前的狀態或者內容。
(function( $ ){ var methods = { init : function( options ) { return this.each(function(){ var $this = $(this), data = $this.data('tooltip'), tooltip = $('<div />', { text : $this.attr('title') }); // If the plugin hasn't been initialized yet if ( ! data ) { /* Do more setup stuff here */ $(this).data('tooltip', { target : $this, tooltip : tooltip }); } }); }, destroy : function( ) { return this.each(function(){ var $this = $(this), data = $this.data('tooltip'); // Namespacing FTW $(window).unbind('.tooltip'); data.tooltip.remove(); $this.removeData('tooltip'); }) }, reposition : function( ) { // ... }, show : function( ) { // ... }, hide : function( ) { // ... }, update : function( content ) { // ...} }; $.fn.tooltip = function( method ) { if ( methods[method] ) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.tooltip' ); } }; })( jQuery );