如何在单个页面上拥有多个jQuery插件实例?

我正在编写一个简单的jQuery插件,但是我无法在页面上使用多个实例。

例如,这是一个示例插件来说明我的观点:

(function($) { $.fn.samplePlugin = function(options) { if (typeof foo != 'undefined') { alert('Already defined!'); } else { var foo = 'bar'; } }; })(jQuery); 

如果我这样做:

 $(document).ready(function(){ $('#myDiv').samplePlugin({}); // does nothing $('#myDiv2').samplePlugion({}); // alerts "Already defined!" }); 

这显然是一个过于简化的例子来说明问题。 所以我的问题是,我如何有两个单独的插件实例? 我希望能够在同一页面上的多个实例中使用它。

我猜测问题的一部分可能是在全局范围内定义变量。 那么如何定义它们对插件实例的唯一性呢?

谢谢你的指导!

我有同样的问题,但我发现一个非常方便的解决方案,我会发布给可能有这个问题的人

当您在插件中定义变量时,您可以使用.data()来存储您定义的所有变量

像这样

 (function($) { $.fn.samplePlugin = function(options) { var base = this; this.foo // define foo // do stuff with foo and other variables // Add a reverse reference to the DOM object this.data("pluginname", base); };})(jQuery); 

当你想使用相同的foo变量时,你应该用这个来检索引用:

 base = this.data("pluginname"); base.foo 

希望能帮助到你

洛根

我不确定你有多个插件实例是什么意思。 插件可用于任何元素。

这条评论对我来说并不是很清楚:

所以说它是一个插件,它采用了“颜色”参数并将对象转换为该颜色。 那么,在这种情况下,你需要多个实例,因为你正在处理多个页面元素,转换多种颜色。

在这种情况下,您可以根据需要传递不同颜色的参数:

 $('div#foo').makeColor('red'); $('div#bar').makeColor('blue'); 

每次调用插件时,它都会使用您提供的任何参数。 该插件不是需要实例的类。

HTML:

 resize1 resize2      

我找到了2个解决方案 – 第一个是jquery widget factory http://jqueryui.com/widget/js代码:

 $.widget("custom.ratiofix",{ options:{ message:"nothing" }, _create:function (){ var self=this; this.setListeners(); }, setListeners:function (){ var self=this; $(window).on('resize',$.proxy(self.printMsg,self)); }, printMsg:function (){ console.log(this.options.message); } }); 

第二个(没有小部件工厂):

 (function ($){ var Ratiofix = { init: function(options, elem) { this.options = $.extend({},this.options,options); this.elem = elem; this.$elem = $(elem); this.setListeners(); return this; }, options: { message: "No message" }, printMsg: function(){ console.log(this.options.message); }, setListeners:function (){ var self=this; this.$elem.on('click',function (){ console.log(self.options.message); }); $(window).on('resize',$.proxy(self.printMsg, self)); } }; $.fn.ratiofix=function (options){ this.init= function(options, elem) { this.options = $.extend({},this.options,options); this.elem = elem; this.$elem = $(elem); return this; }; if ( this.length ) { return this.each(function(){ var ratiofix = Object.create(Ratiofix); ratiofix.init(options, this); $.data(this, 'ratiofix', ratiofix); }); } }; })(jQuery); 

在这两种情况下,插件都单独工作并具有自己的设置。 在我的情况下 – 2个小部件监听窗口resize并打印到控制台自己的options.message

把我的解决方案放在这里:

 (function ($){ $.fn.plugin = function (options){ var settings = $.extend({}, $.fn.plugin.defaults, options); settings.that = $(this); $.fn.plugin.init (settings); }; $.fn.plugin.defaults = { objval: 'default' }; $.fn.plugin.init = function (settings){ settings.that.val (settings.objval); }; }( jQuery )); $('#target1').plugin ({objval: 'not default'}); $('#target2').plugin (); 

DEMO

每次初始化对象时,都会隔离设置变量。

要直接回答您的问题,您可以使用jQuery.noconflict()来避免命名空间冲突,从而可能在页面上有多个实例化。

 var $j = jQuery.noConflict(); // Use jQuery via $j(...) $j(document).ready(function() { // etc 

在这里查看

但我质疑你的设计。 你为什么要编写一个似乎不能在jQuery包装集上运行的插件? 应该编写插件,假设它们在“this”中保存的jQuery数组上运行。 在这种情况下,任何状态都可以存储在每个被采取行动的项目中……但也许你正在构建不同的东西?

请查看此页面

而不是写这个

 $("#divid1").samplePlugin(); $("#divid2").samplePlugin(); 

你可以这样做

 $.plugin('samplePlugin1', samplePlugin); $("#divid1").samplePlugin1(); $.plugin('samplePlugin2', samplePlugin); $("#divid2").samplePlugin2(); 

您可以从http://alexsexton.com/?p=51获取更多详细信息

您需要使用this.foo而不是var foo ,以便变量仅与当前对象相关。

这对我有用! 我有特定的参数,我希望运行插件的页面/位置,并通过使用简单的if语句获得成功。 希望这有助于某人!

   0) { ?>      

我遇到了同样的问题:如何在一个表单上使用插件的许多实例? 通常的方法失败,因为实际上,实例不是插件的实例:它是jQuery的一个实例。 因此,如果定义了多个元素由插件管理,则每个定义都会覆盖以前的参数。

有必要从另一方面看问题。

插件通常用于对特定元素的特定事件做出反应。 例如。 单击按钮,或当鼠标hover在元素上时。 在我的情况下,我必须为城市字段使用自动完成插件,但我的表单有5个选项卡,总共4个字段用于城市,用于收集信息的4个不同部分。 对于每个字段,参数都是细节。

顺便说一句,我已经意识到我不需要每次都让插件处于活动状态:只需在场上的相应事件就足够了。

所以我有了一个想法:每个元素的事件管理器。 当事件追加时,我定义了插件动作。 一些代码将更有效地解释:想象你有3个div块,你的插件必须改变颜色,但具体的颜色取决于哪个div受影响。

 $(document).ready(function(){ // Wich elements are affected by the plugin var ids = ['myDiv1','myDiv2','myDiv3']; // foe each one : for (v in ids) { //define from an event : $('#'+ ids[v]).focus(function() { // depending which id is active : var aParams, idDiv = $(this).attr('id'); // Choosing the right params switch(idDiv) { case 'myDiv1': aParams = {'color': '#660000', 'background-color': '#0000ff'}; break; case 'myDiv2': aParams = {'color': '#006600', 'background-color': '#ff00ff'}; break; case 'myDiv3': aParams = {'color': '#000066', 'background-color': '#ff0000'}; break; default: aParams = {'color': '#000000', 'background-color': '#ffffff'}; }; // Defining the plugin on the right element with the right params $(this).myPlugin( { colors: aParams }); }); } }); 

这很好用。

对不起,如果我的英语不完美 – 我希望你能理解。