Проблема с выбранным в данный момент ответом заключается в том, что вы фактически не создаете новый экземпляр пользовательского плагина для каждого элемента в селекторе, как вы думаете, вы делаете ... вы фактически создаете только один экземпляр и передавая сам селектор в качестве области видимости.
Просмотр этой скрипки для более глубокого объяснения.
Вместо этого вам нужно перебрать селектор с помощью 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, поскольку его рандомизатор всегда установлен в 1 в строке 89). Это потому, что мы сейчас правильно создаем экземпляр нового пользовательского экземпляра плагина для каждого элемента в селекторе. Каждый элемент имеет свой собственный объект параметров и сохраняется не в селекторе, а в случае самого пользовательского плагина.
Это означает, что вы сможете получить доступ к методам пользовательского плагина, созданного на конкретном элементе в DOM, из новых селекторов jQuery и не будете вынуждены их кэшировать, как если бы вы были в первой скрипке. 1024 *
Например, это вернуло бы массив всех объектов параметров, используя технику во второй скрипке. В первом случае он вернет 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
Я бы предложил использовать вышеописанную технику, а не ту, которая выбрана в данный момент.