当前所选答案存在问题,因为您并没有像您认为的那样为选择器中的每个元素创建一个自定义插件的新实例...实际上您只创建了一个单一的实例,并将选择器本身作为范围传递进去。
查看这个fiddle以获取更深入的解释。
相反,您需要使用jQuery.each循环遍历选择器,并为选择器中的每个元素实例化一个自定义插件的新实例。
以下是如何实现:
(function($) {
var CustomPlugin = function($el, options) {
this._defaults = {
randomizer: Math.random()
};
this._options = $.extend(true, {}, this._defaults, options);
this.options = function(options) {
return (options) ?
$.extend(true, this._options, options) :
this._options;
};
this.move = function() {
$el.css('margin-left', this._options.randomizer * 100);
};
};
$.fn.customPlugin = function(methodOrOptions) {
var method = (typeof methodOrOptions === 'string') ? methodOrOptions : undefined;
if (method) {
var customPlugins = [];
function getCustomPlugin() {
var $el = $(this);
var customPlugin = $el.data('customPlugin');
customPlugins.push(customPlugin);
}
this.each(getCustomPlugin);
var args = (arguments.length > 1) ? Array.prototype.slice.call(arguments, 1) : undefined;
var results = [];
function applyMethod(index) {
var customPlugin = customPlugins[index];
if (!customPlugin) {
console.warn('$.customPlugin not instantiated yet');
console.info(this);
results.push(undefined);
return;
}
if (typeof customPlugin[method] === 'function') {
var result = customPlugin[method].apply(customPlugin, args);
results.push(result);
} else {
console.warn('Method \'' + method + '\' not defined in $.customPlugin');
}
}
this.each(applyMethod);
return (results.length > 1) ? results : results[0];
} else {
var options = (typeof methodOrOptions === 'object') ? methodOrOptions : undefined;
function init() {
var $el = $(this);
var customPlugin = new CustomPlugin($el, options);
$el.data('customPlugin', customPlugin);
}
return this.each(init);
}
};
})(jQuery);
还有一个可运行的代码片段。
你会注意到,在第一个代码片段中,所有的div元素总是向右移动了完全相同的像素。这是因为只有一个选项对象用于选择器中的所有元素。
使用上面所述的方法,你会发现在第二个代码片段中,每个div元素都没有对齐并且随机移动(除了第一个div元素,因为它的随机数生成器在第89行始终设置为1)。这是因为我们现在为选择器中的每个元素适当地实例化了一个新的自定义插件实例。每个元素都有自己的选项对象,并且不保存在选择器中,而是保存在自定义插件实例中。
这意味着你可以从新的jQuery选择器中访问在DOM中特定元素上实例化的自定义插件的方法,并且不必像在第一个代码片段中那样强制缓存它们。
例如,使用第二个代码片段中的技术将返回所有选项对象的数组。在第一个代码片段中,它将返回undefined。
$('div').customPlugin();
$('div').customPlugin('options');
这是您需要在第一个fiddle中访问选项对象的方式,它仅返回单个对象,而不是对象数组:
var divs = $('div').customPlugin();
divs.customPlugin('options');
$('div').customPlugin('options');
我建议使用上面的技巧,而不是当前选定答案中的技巧。