关于Addy Osmani的jQuery插件模式:调用函数

时间:2014-02-19 18:54:14

标签: javascript jquery design-patterns

我正在使用Addy Osmani出色的jQuery插件模式来编写一个jQuery插件(http://addyosmani.com/resources/essentialjsdesignpatterns/book/#jquerypluginpatterns),但是有些东西让我对他在原型中添加函数的方式感到困惑:

// The actual plugin constructor
function Plugin( element, options ) {
    this.element = element;

    // jQuery has an extend method that merges the
    // contents of two or more objects, storing the
    // result in the first object. The first object
    // is generally empty because we don't want to alter
    // the default options for future instances of the plugin
    this.options = $.extend( {}, defaults, options) ;

    this._defaults = defaults;
    this._name = pluginName;

    this.init();
}

Plugin.prototype.init = function () {
    // Place initialization logic here
    // We already have access to the DOM element and
    // the options via the instance, e.g. this.element
    // and this.options
};

在本节中,他调用了“this.init()”,这是一个添加到插件原型的函数,但是如果我将自己的函数添加到原型中,我无法从“this”更改的任何地方调用它范围。

E.g。

Plugin.prototype.foo = function() {};

无法从:

调用
$('.some-class).each(function() {
  this.foo();
});

因为'this'指的是选择中的每个元素。

如何以标准方式从插件中调用方法和函数? 这些方法也不起作用:

Plugin.foo();
this.foo();

编辑:实际代码:

;(function ($, window, document, undefined) {

    var pluginName = 'slider',
        defaults = {
            speed: 1000,
            pause: 5000
        };


    function Plugin(element, options) {

        this.element = element;
        this.options = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }


    Plugin.prototype.init = function () {

        var $slider,
            $controls;

        $slider = $(this.element);
        $controls = $slider.find('.slider__controls');

        $controls.each(function(index) {

            // How do I call 'showControl();'?

        });

    };


    Plugin.prototype.showControl = function() {

        // Do things.

    };


    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options));
            }
        });
    }

})(jQuery, window, document);

1 个答案:

答案 0 :(得分:1)

请参阅How to access the correct `this` context inside a callback?

Plugin.prototype.init = function () {
    var $slider = $(this.element),
        $controls = $slider.find('.slider__controls'),
        pluginInstance = this;

    $controls.each(function(index) {
        pluginInstance.showControl(this);
    });
};