2012-05-16 111 views
2

我正在使用jQuery插件樣板文件herejQuery插件多實例化

但是它提到了構造函數可以防止多重實例化,並且我想知道爲了修改它以允許多個實例化,我需要做些什麼?

插件樣板如下:

// the semi-colon before function invocation is a safety net against concatenated 
// scripts and/or other plugins which may not be closed properly. 
;(function ($, window, undefined) { 

// undefined is used here as the undefined global variable in ECMAScript 3 is 
// mutable (ie. it can be changed by someone else). undefined isn't really being 
// passed in so we can ensure the value of it is truly undefined. In ES5, undefined 
// can no longer be modified. 

// window and document are passed through as local variables rather than globals 
// as this (slightly) quickens the resolution process and can be more efficiently 
// minified (especially when both are regularly referenced in your plugin). 

// Create the defaults once 
var pluginName = 'defaultPluginName', 
    document = window.document, 
    defaults = { 
    propertyName: "value" 
    }; 

// The actual plugin constructor 
function Plugin(element, options) { 
this.element = element; 

// jQuery has an extend method which merges the contents of two or 
// more objects, storing the result in the first object. The first object 
// is generally empty as we don't want to alter the default options for 
// future instances of the plugin 
this.options = $.extend({}, defaults, options) ; 

this._defaults = defaults; 
this._name = pluginName; 

this.init(); 
} 

Plugin.prototype.init = function() { 
// Place initialization logic here 
// You already have access to the DOM element and the options via the instance, 
// e.g., this.element and this.options 
}; 

// A really lightweight plugin wrapper around the constructor, 
// preventing against multiple instantiations 
$.fn[pluginName] = function (options) { 
return this.each(function() { 
    if (!$.data(this, 'plugin_' + pluginName)) { 
    $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); 
    } 
}); 
} 

}(jQuery, window)); 

在具體的構造部分是:

// A really lightweight plugin wrapper around the constructor, 
// preventing against multiple instantiations 
$.fn[pluginName] = function (options) { 
    return this.each(function() { 
    if (!$.data(this, 'plugin_' + pluginName)) { 
     $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); 
    } 
    }); 
} 

最終,如果插件被用來設置一些事件的元件上,我會喜歡能打電話:

$('#example1').myplugin({options}); 
$('#example2').myplugin({options}); 

回答

1
if (!$.data(this, 'plugin_' + pluginName)) { 
    $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); 
} 

刪除,並與剛剛

new Plugin(this, options); 

它將不再檢查其已在元件上先前已實例,只是初始化插件,無論更換。但是請記住,如果插件覆蓋以前的實例,或者無論如何修改前一個實例,這可能會導致衝突或錯誤問題。所以確保你的插件是用這個心智編碼的

+0

這很有道理。我現在就試試這個。 – Houdmont

+0

這恐怕不行。我調用$('example1')。plugin()並且插件被實例化,然後我調用$('example2')。plugin()和example2元素受插件的影響,但example1停止受到影響。 – Houdmont

+0

停止多個實例的代碼是每個元素。如果你想在2個元素上初始化它,你不需要刪除代碼。它基本上停止運行$('#xxx')。plugin();偶然發生兩次並導致問題。 您需要提供插件代碼和詳細說明。如果你需要快速幫助,JSFiddle也是一個不錯的選擇 – Lee

0

你需要擴展每個實例的默認值/選項。請記住,JavaScript對象只是一個引用,所以如果您要更改構造函數中的選項,您將更改所有其他元素引用的對象。

// A really lightweight plugin wrapper around the constructor, 
// preventing against multiple instantiations 
$.fn[pluginName] = function (options) { 
    return this.each(function() { 
    if (!$.data(this, 'plugin_' + pluginName)) { 
    //extend your options in here 
     var newOptions = $(true, {}, $.fn[name].opts, options); 
     $.data(this, 'plugin_' + pluginName, new Plugin(this, newOptions)); 
    } 
    }); 
} 
2

多個實例,你需要爲每個實例的新閉合,試試下面的代碼:

// A really lightweight plugin wrapper around the constructor, 
// preventing against multiple instantiations 
$.fn[pluginName] = function (options) { 
    return this.each(function() { 
     if (!$.data(this, 'plugin_' + pluginName)) { 
      $.data(this, 'plugin_' + pluginName, 
      new Plugin(this, options)); 
     } 
    }); 
} 

您可以按照本指南,瞭解更多有關防止對多個實例: jQuery Plugin Patterns