“私人”jQuery插件

时间:2013-03-21 18:30:49

标签: jquery jquery-plugins

我已经在互联网上搜索了这个答案,但无济于事。我觉得答案可能很简单,但它一直在逃避我。

我正在编写一个jQuery插件,并遵循所有最佳实践。假设我的插件名为foo,我有以下标准插件定义:

(function($){
  $.fn.foo = function() {
    this.append('<p>I'm doing stuff!</p>');
  }
})(jQuery);

到目前为止非常基础。现在假设我有一些内部功能,我希望将其封装在名为bar的函数中。不过这里有一个问题:我想把它称为jQuery插件,所以我可以利用链接等等。也就是说,我希望能够像这样使用它:

(function($){
  /* this is bad: it clutters up the namespace, and exposes implementation details:
  $.fn.bar = function(text) {
    this.append('<p>'+text'</p>');
  }
  */
  $.fn.foo = function() {
    this.append('<p>I'm doing stuff!</p>').bar('bar does something else!');
  }
})(jQuery);

如何声明bar以便我可以像jQuery插件一样调用它,但它不能在我的插件范围之外使用?

我使用Javascript的apply方法搞砸了,我得到了一些有用的东西,但它很笨重,并且只比用jQuery对象作为参数调用函数更好。

我确信有一个简单的解决方案......任何人?

1 个答案:

答案 0 :(得分:1)

Ethan,使用主张here的插件模式,存在一系列可能性,包括私有函数和一系列公共方法都在一个插件中。

你可以拥有私人功能,可以想象它们可以连接(各种各样),但是:

  • 您通常无法在内部进行链接,因为内部调用往往是使用.call()
  • 您通常不希望或需要内部可链接性,因为公共方法通常采用return this.each(function(){...});形式,并且在此循环中,代码解决了它所执行的jQuery选择的单个元素。

例如:

(function($){
    // **********************************
    // ***** Start: Private Members *****
    var pluginName = 'foo';
    var cough = function(text, bgColor) {
        text = text || ''; 
        bgColor = bgColor || '#FFF';
        $(this).append($('<p/>').append(text).css('backgroundColor', bgColor));
    };
    // ***** Fin: Private Members *****
    // ********************************

    // *********************************
    // ***** Start: Public Methods *****
    var methods = {
        init: function(text) {
            text = text || 'foo init!';
            return this.each(function() {
                methods.bar.call($(this), 'cough from bar from init');
                cough.call($(this), 'cough from init');
            });
        },
        bar: function(text) {
            text = text || 'cough from bar!';
            return this.each(function() {
                cough.call(this, text, '#99CC99');
            });
        }
    };
    // ***** Fin: Public Methods *****
    // *******************************

    // *****************************
    // ***** Start: Supervisor *****
    $.fn[pluginName] = function( method ) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || !method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' + method + ' does not exist in jQuery.' + pluginName );
        }
    };
    // ***** Fin: Supervisor *****
    // ***************************
})(jQuery);

这里的插件'foo'有一个公共方法'init'和'bar',以及一个私有实用程序'cough',由init和'bar'内部调用。

你可以打电话

$("div").foo(); //same as $("div").foo(init');
$("div").foo('bar', 'cough from bar');

cough无法在外部调用。

注意:在上面的模式中,主管总是完全相同 - 不需要编辑。