当前选择的答案的问题在于,您实际上并没有像您认为的那样为选择器中的每个元素创建自定义插件的新实例……您实际上只是创建了一个实例并传入选择器本身作为范围。
查看这个小提琴以获得更深入的解释。
相反,您需要使用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'); // would return an array of all options objects
这就是您必须访问第一个小提琴中的选项对象的方式,并且只会返回一个对象,而不是它们的数组:
var divs = $('div').customPlugin();
divs.customPlugin('options'); // would return a single options object
$('div').customPlugin('options');
// would return undefined, since it's not a cached selector
我建议使用上述技术,而不是当前选择的答案中的技术。