0

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

我正在编写一个 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 对象作为参数调用函数更好。

我确定有一个简单的解决方案...有人吗?

4

1 回答 1

1

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

您可以拥有私有函数,并且可以想象它们是可链接的(某种程度上),但是:

  • 您通常不能在内部进行链接,因为内部调用往往使用.call().
  • 您通常不希望或需要内部可链接性,因为公共方法通常是 form 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'和'bar'调用。

你可以打电话

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

但是cough不能被外部调用。

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

于 2013-03-21T20:57:46.807 回答