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 !!!

在底部,您可以看到我如何调用插件方法。

第一个问题:有没有更简洁的方法来获取“this”/方法中的对象?我认为首先在插件外部定义 var,然后在插件内部,然后在 init-function 内部定义是很不酷的。有没有更清洁的方法来做到这一点?

正如您在底部看到的:我只想在 if 语句为真时调用插件。如果它是真的,那么它会调用 init。然后我调用插件的一个方法,它也可以正常工作,因为“$this”是之前定义/初始化的。但是如果 if-statment 不正确并且插件的“init”-method 没有被调用……我认为可以调用插件的方法是不合逻辑的。

所以这是问题 #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'));
    }
};

对于第二个问题,您可以在第一次调用插件时将数据附加到 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

这就是我想要的(感谢所有人):

(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

做了一些改动:

  • 如果其他插件使用相同的技术,数据值还必须包含插件名称以防止错误行为。
  • 在第二个 if 语句中添加了“is_init”
于 2012-11-30T12:19:38.887 回答