web-dev-qa-db-ja.com

1つのページに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!"
});

これは明らかに、要点を理解するための過度に単純化された例です。 私の質問は、プラグインの2つの別々のインスタンスを作成するにはどうすればよいですか?同じページの複数のインスタンスでプラグインを使用できるようにしたいと思います。

問題の一部は、グローバルスコープで変数を定義することにあるのではないかと思います。プラグインのそのインスタンスに固有のそれらをどのように定義できますか?

ご指導ありがとうございます!

17
James Skidmore

私はまったく同じ問題を抱えていますが、この問題を抱えている可能性のある人のために投稿する非常に便利な解決策を見つけました

プラグイン内で変数を定義するときは、.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

それが役に立てば幸い

ローガン

17
Logan

プラグインのインスタンスが複数あるとはどういう意味かわかりません。プラグインは、どの要素でも使用できます。

このコメントは私にはあまり明確ではありません:

つまり、「color」パラメータを取り、オブジェクトをその色に変えたプラグインだったとしましょう。その場合、複数のページ要素が複数の色に変わるので、複数のインスタンスが必要になります。

この場合、必要に応じてさまざまな色の引数を渡します。

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

プラグインを呼び出すたびに、プラグインは指定された引数を使用します。プラグインはインスタンスを必要とするクラスではありません。

2
Nathan Long

ここに私の解決策を投げるだけです:

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

[〜#〜]デモ[〜#〜]

設定変数は、オブジェクトを初期化するたびに分離されます。

2
Scott M

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つの解決策を見つけました-最初のものはjqueryウィジェットファクトリーです 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);
    }
});

そして2番目(ウィジェットファクトリなし):

(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つのウィジェットがウィンドウのサイズ変更をリッスンし、コンソール独自のoptions.messageに出力します

2
Roman Yudin

これを書く代わりに

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

あなたはこのようにすることができます

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

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

あなたはここから多くの詳細を持つことができます http://alexsexton.com/?p=51

1
manny

変数が現在のオブジェクトにのみ関連するように、this.fooの代わりにvar fooを使用する必要があります。

1
WhyNotHugo

質問に直接答えるには、jQuery.noconflict()を使用して名前空間の衝突を回避し、ページ上に複数のインスタンス化を行う可能性があります。

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

チェック ここ

しかし、私はあなたのデザインに疑問を持っています。 jQueryでラップされたセットで動作しないように見えるプラグインを作成しているのはなぜですか? ..プラグインは、「this」に保持されているjQuery配列で動作していると想定して作成する必要があります。その場合、影響を受ける各アイテムに任意の状態を保存できます...しかし、おそらくあなたは何か違うものを構築しているのでしょうか?

確認してください このページ

1
Scott Evernden