0

ここに表示されるのは、プラグインから始める方法です。

(function($){
    var methods = {
        init: function(){
            $this = this;
            alert('init '+$this.attr('id'));
        }
        ,
        show_id: function(){
            alert($this.attr('id'));
        }
    };

    var $this;
    // other vars

    $.fn.my_plug = function(method){
        var args = arguments;
        var $this = this;
        return this.each(function(){
            if (methods[method]){
                return methods[method].apply($this, Array.prototype.slice.call(args, 1));
            } else if (typeof method === 'object' || !method){
                return methods.init.apply($this, Array.prototype.slice.call(args, 0));
            } else {
                $.error('Method '+method+' does not exist!');
            }  
        });
    };
})(jQuery);

var a = true;

if (a) $('#object').my_plug(); // alerts "init object"

$('#object').my_plug('show_id'); // alerts "object"

var b = false;

if (b) $('#object_b').my_plug(); // does nothing

$('#object_b').my_plug('show_id'); // calls "show_id"-method … but $this is not defined. It should NOT call because this object is not initialized !!!

下部に、プラグイン メソッドの呼び出し方法が表示されます。

最初の質問:「これ」/メソッド内のオブジェクトを取得するよりクリーンな方法はありますか? 最初にプラグインの外側で var を定義し、次にプラグインの内側で、次に init-function の内側で定義するのは非常にクールではないと思います。これを行うためのよりクリーンな方法はありますか?

下部にあるように、if ステートメントが true の場合にのみプラグインを呼び出します。true の場合は、init を呼び出します。次に、「$this」が以前に定義/初期化されているため、これも正常に機能するプラグインのメソッドを呼び出します。しかし、if ステートメントが真ではなく、プラグインの「init」メソッドが呼び出されていない場合…プラグインのメソッドを呼び出すことができるのは論理的ではないと思います。

質問 #2: オブジェクトが初期化されていない場合、メソッドの呼び出しを防ぐにはどうすればよいですか? プラグインを初期化していないため、呼び出し$('#object_b').my_plug('show_id');ても何もしないはずです。プラグインが初期化されている場合、または "$this" が定義されている場合にのみ使用できます。

どう思いますか?

4

2 に答える 2

1

最初の質問では、プラグインの外で $this 変数を宣言する必要はありません。thisスコープでメソッドを呼び出しているため。thisメソッドで利用できるようになります。そして、あなたができることは

    var methods = {
    init: function(){
        var $this = $(this);     //local to this function
        alert('init '+$this.attr('id'));
    }
    ,
    show_id: function(){
        var $this = $(this);
        alert($this.attr('id'));
    }
};

2 番目の質問では、最初にプラグインを呼び出すときにデータを dom オブジェクトにアタッチできます。このオブジェクトでプラグインが初期化されているかどうかは、後続の呼び出しで確認できます。

    $.fn.my_plug = function(method){
    var args = arguments;
    return this.each(function() {
        var $this = $(this),
            data = $this.data('your-plugin-inited'); //e.g.

        if (!data) {    //if no data is attached you can call init
            data = $this.data('your-plugin-inited', 1);
            return methods.init.apply($this, Array.prototype.slice.call(args, 0));
        }

        if (methods[method]){
            return methods[method].apply($this, Array.prototype.slice.call(args, 1));
        } else {
            $.error('Method '+method+' does not exist!');
        }  
    });
  }

フィドルでチェックしてくださいhttp://jsfiddle.net/tqvjt/6/

プラグインのオーサリングに関する洞察を深めるために、jQuery プラグイン パターンをお勧めします。 http://coding.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns

于 2012-11-30T10:25:31.143 に答える
0

これが私が欲しかったものです(すべてthx):

(function($){
    var methods = {
        init: function(){
            alert('init '+ this.attr('id'));
            //this.my_plug('show_id'); //call from inside the plugin
        }
        ,
        show_id: function(){
            alert(this.attr('id'));
        }
    };

    $.fn.my_plug = function(method){
        var args = arguments;
        var init = 'init-my_plug';
        return this.each(function() {
            var is_init = $(this).data(init);
            if (methods[method] && is_init){
                return methods[method].apply($(this), Array.prototype.slice.call(args, 1));
            } else if (!is_init && (typeof method === 'object' || !method)){
                $(this).data(init, true);
                return methods.init.apply($(this), Array.prototype.slice.call(args, 0));
            }
        });
    };
})(jQuery);

var a = true; // if a is set to false nothing happens

if (a) $('div').my_plug();
$('div').my_plug('show_id');
$('#div3').my_plug('show_id'); // also works on only one of the divs​​​​​​​​​​

試してみてください: jsfiddle

いくつかの変更を行いました:

  • 他のプラグインが同じ手法を使用している場合に誤った動作を防ぐために、data-value には plugin-name も含める必要があります。
  • 2 番目の if 文に「is_init」を追加
于 2012-11-30T12:19:38.887 に答える