Le problème avec la réponse actuellement sélectionnée est que vous ne créez pas réellement une nouvelle instance du plugin personnalisé pour chaque élément du sélecteur comme vous pensez que vous le faites ... le sélecteur lui-même comme champ d'application.
Regardez ce violon pour une explication plus approfondie.
Au lieu de cela, vous devrez parcourir le sélecteur en utilisant jQuery.each et instancier une nouvelle instance du plugin personnalisé pour chaque élément du sélecteur.
Voici comment:
(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);
Et un violon qui fonctionne .
Vous remarquerez que dans le premier violon, tous les div sont toujours déplacés vers la droite du même nombre de pixels. En effet, un seul objet d'options existe pour tous les éléments du sélecteur.
En utilisant la technique écrite ci-dessus, vous remarquerez que dans le deuxième violon, chaque div n'est pas aligné et est déplacé aléatoirement (à l'exclusion du premier div car son randomiseur est toujours réglé sur 1 à la ligne 89). C'est parce que nous instancions maintenant correctement une nouvelle instance de plugin personnalisée pour chaque élément du sélecteur. Chaque élément a son propre objet d'options et n'est pas enregistré dans le sélecteur, mais dans l'instance du plugin personnalisé lui-même.
Cela signifie que vous serez en mesure d'accéder aux méthodes du plugin personnalisé instancié sur un élément spécifique du DOM à partir de nouveaux sélecteurs jQuery et que vous ne serez pas obligé de les mettre en cache, comme vous le seriez dans le premier violon.
Par exemple, cela renvoie un tableau de tous les objets d'options en utilisant la technique du second violon. Il reviendrait indéfini dans le premier.
$('div').customPlugin();
$('div').customPlugin('options');
Voici comment vous devriez accéder à l'objet d'options dans le premier violon, et ne retourneriez qu'un seul objet, pas un tableau d'entre eux:
var divs = $('div').customPlugin();
divs.customPlugin('options');
$('div').customPlugin('options');
Je suggère d'utiliser la technique ci-dessus, pas celle de la réponse actuellement sélectionnée.