我正在使用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);
答案 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);
});
};