Проблема з обраною на даний момент відповіддю полягає в тому, що ви насправді не створюєте новий примірник спеціального плагіна для кожного елемента в селекторі, як ви думаєте, що це робите ... ви фактично створюєте лише один екземпляр і передаєте сам селектор як область застосування.
Вид цю загадку для глибшого пояснення.
Замість цього вам потрібно буде провести циклічний пошук через селектор 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 не вирівнюється і переміщується випадковим чином (за винятком першого діла, оскільки його випадковий розмір завжди встановлений на 1 у рядку 89). Це тому, що ми зараз належним чином створюємо новий екземпляр додаткового модуля для кожного елемента в селекторі. Кожен елемент має власний об'єкт параметрів і зберігається не в селекторі, а в екземплярі самого користувацького плагіна.
Це означає, що ви зможете отримати доступ до методів користувальницького плагіна, створеного на конкретному елементі в DOM, з нових селекторів jQuery, і ви не змушені будете кешувати їх, як це було б у першій скрипці.
Наприклад, це поверне масив усіх об'єктів параметрів, використовуючи техніку у другій скрипці. Він повернеться невизначеним у першому.
$('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
Я б запропонував скористатися вищенаведеною технікою, а не тією, яку ви обрали на даний момент.