Javascript 如何在一个页面上有多个jQuery插件实例?

Javascript 如何在一个页面上有多个jQuery插件实例?,javascript,jquery,plugins,jquery-plugins,Javascript,Jquery,Plugins,Jquery Plugins,我正在编写一个简单的jQuery插件,但在一个页面上使用多个实例时遇到了困难 例如,下面是一个示例插件来说明我的观点: (function($) { $.fn.samplePlugin = function(options) { if (typeof foo != 'undefined') { alert('Already defined!'); } else { var foo = 'bar'; } }; })(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!"
});
显然,这是一个过于简化的例子来说明问题所以我的问题是,如何拥有该插件的两个独立实例?我希望能够在同一页面上的多个实例中使用它

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


谢谢你的指导

我不知道你说的一个插件有多个实例是什么意思。插件可以在任何元素上使用

这一评论对我来说并没有太多的澄清:

所以说这是一个插件 一个“颜色”参数,并将 物体变成那种颜色。嗯,在那方面 在这种情况下,您需要多个实例,如 您处理的页面不止一页 元素转换为多种颜色

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

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

每次你调用插件时,它都会使用你给它的任何参数。插件不是一个需要实例的类。

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

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

但我怀疑你的设计。为什么要编写一个插件,它似乎不在jQuery包装集上运行。。编写插件时应假定它们在“this”中保存的jQuery数组上运行。在这种情况下,任何状态都可以存储在每个被操作的项中。。。但也许你在建造一些不同的东西


请回顾一下

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

有必要从另一个角度来看待这个问题

插件通常用于对特定元素的特定事件做出反应。e、 g..onclick一个按钮,或者当鼠标在元素上时。 在我的例子中,我不得不为一个城市字段使用一个自动完成插件,但我的表单有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
            });
        });
    }
});
这个很好用


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

我也有同样的问题,但我找到了一个非常方便的解决办法,我会把它贴给可能有这个问题的人

在插件中定义变量时,可以使用.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
希望能有帮助


洛根

而不是写这个

$("#divid1").samplePlugin();
$("#divid2").samplePlugin();
你可以这样做

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

$.plugin('samplePlugin2', samplePlugin);
$("#divid2").samplePlugin2();
你可以从这里得到很多细节

这对我来说是一种享受!我有特定的参数,我想运行插件的页面/位置,并且能够通过使用简单的if语句获得成功。希望这对别人有帮助

<!-- Begin JQuery Plugin Foo -->
<script src="js/foo_fun.js"></script>

<?php 
if(substr_count(strtolower($currentUrl),"member")>0)
{
?>
    <script>
    $(document).ready(function(){
        $('#vscroller').vscroller({newsfeed:'news_employee.xml', speed:1000,stay:2000,cache:false});
    });
    </script>
<?php
}
else
{
?>
    <script>
    $(document).ready(function(){
        $('#vscroller').vscroller({newsfeed:'news_company.xml', speed:1000,stay:2000,cache:false});
    });
    </script>
<?php
}
?>
<!-- End JQuery Foo--> 

$(文档).ready(函数(){
$('#vscroller').vscroller({newsfeed:'news_employee.xml',速度:1000,停留时间:2000,缓存:false});
});
$(文档).ready(函数(){
$('#vscroller').vscroller({newsfeed:'news_company.xml',速度:1000,停留时间:2000,缓存:false});
});

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

只需将我的解决方案放入此处:

(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 ();

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

html:

<code class="resize1">resize1</code>
<code class="resize2">resize2</code>


<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<script type="text/javascript">
       jQuery(document).ready(function($) {
           $('.resize1').ratiofix({message:'resize1'});
           $('.resize2').ratiofix({message:'resize2'});
       });
</script>
第二个(不含小部件工厂):


在这两种情况下,插件分别工作,并有自己的设置。在我的例子中-2个小部件听窗口调整和打印控制台自己的选项。消息

谢谢Nathan,我很感激!示例:应该
if(typeof foo=='undefined')
不是
if(typeof foo!='undefined')
@Hailwood,是的,你是对的。谢谢这更像是一个黑客!如果页面上有许多地方需要执行此操作,则会降低代码的可读性和凌乱性。最好的选择是修复根本原因,即插件的多次初始化。
$.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);