jQuery 插件中的公共函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1034306/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 10:27:48  来源:igfitidea点击:

Public functions from within a jQuery plugin

jqueryajaxpreloader

提问by Daniel

I love the jQuery plugin architecture, however, I find it frustrating (probably due to a lack of understanding on my part) when I want to retain a reference to the plugin instance to access properties or methods later on in my code.

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

Edit: I want to clarify that what I am really trying to do is retain a reference to the methods and properties used within the plugin, so that I can use them later

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

Lets take the case of a AJAX loading icon. In a more traditional OOP environment, I could do:

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

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

The methods and properties of my object are stored on a variable for later use. Now if I want to have the same functionality in a jQuery plugin, I would call it from my main code somewhat like this:

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

$("#myId").ajaxIcon()

By convention, my plugin needs to return the original jQuery object passed to my plugin allowing for chainability, but if I do that, I loose the ability to access methods and properties of the plugin instance.

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

Now, I know that you can declare a public function in my plugin, somewhat along the lines of

现在,我知道你可以在我的插件中声明一个公共函数,有点像

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

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

However, without breaking the convention of returning the original jQuery object, I can't retain a reference to the specific instance of the plugin that I want to refer to.

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

I would like to be able to do something like this:

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

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

Any thoughts?

有什么想法吗?

回答by DEfusion

If you do something like the following:

如果您执行以下操作:

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

Then you can access any of your public methods:

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

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

myPlugin.bar();

This is taken from this very helpful article(May 2009) from trulyevil.com which is itself an extension on this article(Oct 2007) from learningjquery.com.

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

回答by Daniel

Ok, i figured out how to do this:

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

Plugin Code:

插件代码:

$.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;
}

Then to use it somewhere else in your code:

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

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

voila, answered my own question :)

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

回答by Josh E

I think you could accomplish what you're looking for with something like this:

我认为你可以用这样的东西来完成你正在寻找的东西:

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

Haven't tested it though - I don't have access to an environment where I can do that atm

虽然还没有测试过 - 我无法访问我可以做那个 atm 的环境

回答by Jony

Sample plugin with all functions:

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

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

回答by Andrew Noyes

Most of the jQuery plugins that I see trying to accomplish this will use an anonymous scope and closures to reference functions and variables unique to that instance. For example, using the following pattern:

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

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

Between the beginning and end of the module, you can declare any functions you want. You won't pollute the global namespace and you can retain access to local variables through closures, that could solve a lot of your problems. Also, don't be afraid to use the $.datafunctions.

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