33

我喜欢 jQuery 插件架构,但是,当我想保留对插件实例的引用以稍后在我的代码中访问属性或方法时,我发现它令人沮丧(可能是由于我缺乏理解)。

编辑:我想澄清一下,我真正想做的是保留对插件中使用的方法和属性的引用,以便以后可以使用它们

让我们以 AJAX 加载图标为例。在更传统的 OOP 环境中,我可以这样做:

var myIcon = new AJAXIcon();
myIcon.start();
//some stuff
myIcon.stop();

我的对象的方法和属性存储在一个变量中供以后使用。现在,如果我想在 jQuery 插件中拥有相同的功能,我会从我的主代码中调用它,有点像这样:

$("#myId").ajaxIcon()

按照惯例,我的插件需要返回传递给我的插件的原始 jQuery 对象,以实现可链接性,但如果这样做,我将失去访问插件实例的方法和属性的能力。

现在,我知道您可以在我的插件中声明一个公共函数,有点类似于

$.fn.ajaxIcon = function(options) {
    return this.each(function () {
        //do some stuff
    }
}

$.fn.ajaxIcon.stop = function() {
    //stop stuff
}

但是,在不打破返回原始 jQuery 对象的约定的情况下,我不能保留对我想要引用的插件的特定实例的引用。

我希望能够做这样的事情:

var myIcon = $("myId").ajaxIcon(); //myIcon = a reference to the ajaxIcon 
myIcon.start();
//some stuff
myIcon.stop();

有什么想法吗?

4

5 回答 5

92

如果您执行以下操作:

(function($){

$.fn.myPlugin = function(options) {
    // support multiple elements
    if (this.length > 1){
        this.each(function() { $(this).myPlugin(options) });
        return this;
    }

    // private variables
    var pOne = '';
    var pTwo = '';
    // ...

    // private methods
    var foo = function() {
        // do something ...
    }
    // ...

    // public methods        
    this.initialize = function() {
        // do something ...
        return this;
    };

    this.bar = function() {
        // do something ...
    };
    return this.initialize();
}
})(jQuery);

然后你可以访问你的任何公共方法:

var myPlugin = $('#id').myPlugin();

myPlugin.bar();

这取自 realevil.com 的这篇非常有用的文章(2009 年 5 月),它本身就是 learningjquery.com 的这篇文章(2007 年 10 月)的扩展。

于 2009-06-25T12:38:58.407 回答
3

好的,我想出了如何做到这一点:

插件代码:

$.ajaxIcon.init = function(element, options) {
    //your initialization code

    this.start = function() {
         //start code
    }

    this.stop = function() {
         //stop code
    }
}

$.fn.ajaxIcon = function(options) {
    this.each(function () {
        //This is where the magic happens
        jQuery(this).data('ajaxIcon', new jQuery.ajaxIcon.init(this, opts));
    });

return this;
}

然后在代码中的其他地方使用它:

var myIcon = $("#myId").ajaxIcon.data('ajaxIcon') 
// myIcon: a reference to the 'init' object specific to this plugin instance
myIcon.start();
myIcon.stop();

瞧,回答了我自己的问题:)

于 2009-06-23T19:33:35.297 回答
0

我认为您可以通过以下方式完成您正在寻找的东西:

var myIcon = $("myId").ajaxIcon(); //myIcon = a reference to the ajaxIcon 
$.ajaxIcon.start(myIcon);//some stuff
$.ajaxIcon.stop(myIcon);

不过还没有测试过-我无法访问可以执行该 atm 的环境

于 2009-06-23T19:07:05.787 回答
0

具有所有功能的示例插件:

    <script type="text/javascript">
(function( $ ) {

    $.fn.PluginX = function( options ) {
        // Default variables
        // var defaults = {textColor: "#000", backgroundColor: "#fff"}
        // var opts = $.extend( {}, defaults, options );

        // Or
        var settings = $.extend( {}, $.fn.PluginX.defaults, options );

        // Private function
        var privFunc = function(txt) {
            return "Private function " + txt;
        };

        // Public function
        this.pubFunc = function(txt) {
            console.log("\r\nPublic function " + txt);
            return this;
        };

        // Public function2
        this.pubFunc2 = function(txt) {
            console.log("\r\nPublic function " + txt);

            // Private from public
            privFunc("\r\nPrivate function from public -- " + txt);
            return this;
        };

        // Our plugin implementation code goes here.
        return this.each(function() {
            // alert(opts.validate);
            $(this).on('click',function(){
                var elem = $( this );
                var markup = elem.text();                                
                console.log("\r\nElement text " + markup);

                // Function private
                console.log(privFunc(markup));

                // External func
                console.log($.fn.PluginX.format(markup));

                // External function
                console.log(external(markup));
            });

            return this;
        });
    };

    // Variable
    $.fn.PluginX.defaults = {
        validate: "username"
    };

    // External Function
    $.fn.PluginX.format = function(txt) {
        return "<strong>" + txt + "</strong>";
    };

    // External Function
    function external(txt){
        return "External " + txt;
    }

})(jQuery);

$(document).ready(function() {
    var pl = $('.txt').PluginX({validate: "words"}).pubFunc("Hello Public").pubFunc2("Hello Public2");        
});
</script>
<p class="txt">Hello Max</p>
<p class="txt">Hello Pax</p>
于 2019-07-26T15:58:54.147 回答
-1

我看到的大多数试图实现这一点的 jQuery 插件都将使用匿名范围和闭包来引用该实例独有的函数和变量。例如,使用以下模式:

;(function ($) {
    // your code
})(jQuery);

在模块的开头和结尾之间,您可以声明任何您想要的函数。您不会污染全局命名空间,并且可以通过闭包保留对局部变量的访问,这可以解决您的很多问题。另外,不要害怕使用这些$.data功能。

于 2009-06-23T18:37:22.673 回答