Das Problem mit der aktuell ausgewählten Antwort besteht darin, dass Sie nicht für jedes Element in der Auswahl eine neue Instanz des benutzerdefinierten Plugins erstellen, wie Sie denken ... Sie erstellen tatsächlich nur eine einzelne Instanz und übergeben sie der Selektor selbst als Bereich.
Sehen Sie sich diese Geige für eine tiefere Erklärung an.
Stattdessen müssen Sie den Selektor mit jQuery.each durchlaufen und für jedes Element im Selektor eine neue Instanz des benutzerdefinierten Plugins instanziieren.
Hier ist wie:
(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);
Und eine funktionierende Geige .
Sie werden feststellen, dass in der ersten Geige alle Divs immer genau die gleiche Anzahl von Pixeln nach rechts verschoben werden. Dies liegt daran , dass für alle Elemente im Selektor nur ein Optionsobjekt vorhanden ist.
Wenn Sie die oben beschriebene Technik verwenden, werden Sie feststellen, dass in der zweiten Geige nicht jedes Div ausgerichtet und zufällig verschoben wird (mit Ausnahme des ersten Div, da der Randomizer in Zeile 89 immer auf 1 gesetzt ist). Das liegt daran, dass wir jetzt für jedes Element im Selektor eine neue benutzerdefinierte Plugin-Instanz ordnungsgemäß instanziieren. Jedes Element hat ein eigenes Optionsobjekt und wird nicht im Selektor gespeichert, sondern im Fall des benutzerdefinierten Plugins.
Dies bedeutet, dass Sie über neue jQuery-Selektoren auf die Methoden des benutzerdefinierten Plugins zugreifen können, die für ein bestimmtes Element im DOM instanziiert wurden, und nicht gezwungen sind, sie wie in der ersten Geige zwischenzuspeichern.
Dies würde beispielsweise ein Array aller Optionsobjekte unter Verwendung der Technik in der zweiten Geige zurückgeben. Es würde im ersten undefiniert zurückkehren.
$('div').customPlugin();
$('div').customPlugin('options'); // would return an array of all options objects
Auf diese Weise müssten Sie in der ersten Geige auf das Optionsobjekt zugreifen und nur ein einzelnes Objekt zurückgeben, kein Array davon:
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
Ich würde vorschlagen, die obige Technik zu verwenden, nicht die aus der aktuell ausgewählten Antwort.