2012-06-11 20 views
5

estoy usando el siguiente código como base para un plugin que estoy trabajando para un proyecto - es de un artículo sobre Smashing Magazine se encuentra aquí bajo el título 'Un ligero Inicio':¿Cómo agregaría un método a este patrón de complemento jQuery?

http://coding.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns/

Ha funcionado bien para mis propósitos hasta ahora, pero el resto del artículo se activa en una tangente y habla sobre los widgets de jQuery UI para los que supongo que necesitaría la biblioteca jQuery UI, que realmente no quiero usar .

/*! 
* jQuery lightweight plugin boilerplate 
* Original author: @ajpiano 
* Further changes, comments: @addyosmani 
* Licensed under the MIT license 
*/ 

// the semi-colon before the function invocation is a safety 
// net against concatenated scripts and/or other plugins 
// that are not closed properly. 
;(function ($, window, document, undefined) { 

    // undefined is used here as the undefined global 
    // variable in ECMAScript 3 and is mutable (i.e. it can 
    // be changed by someone else). undefined isn't really 
    // being passed in so we can ensure that its value is 
    // truly undefined. In ES5, undefined can no longer be 
    // modified. 

    // window and document are passed through as local 
    // variables rather than as globals, because this (slightly) 
    // quickens the resolution process and can be more 
    // efficiently minified (especially when both are 
    // regularly referenced in your plugin). 

    // Create the defaults once 
    var pluginName = 'defaultPluginName', 
     defaults = { 
      propertyName: "value" 
     }; 

    // The actual plugin constructor 
    function Plugin(element, options) { 
     this.element = element; 

     // jQuery has an extend method that merges the 
     // contents of two or more objects, storing the 
     // result in the first object. The first object 
     // is generally empty because we don't want to alter 
     // the default options for future instances of the plugin 
     this.options = $.extend({}, defaults, options) ; 

     this._defaults = defaults; 
     this._name = pluginName; 

     this.init(); 
    } 

    Plugin.prototype.init = function() { 
     // Place initialization logic here 
     // You already have access to the DOM element and 
     // the options via the instance, e.g. this.element 
     // and this.options 
    }; 

    // A really lightweight plugin wrapper around the constructor, 
    // preventing against multiple instantiations 
    $.fn[pluginName] = function (options) { 
     return this.each(function() { 
      if (!$.data(this, 'plugin_' + pluginName)) { 
       $.data(this, 'plugin_' + pluginName, 
       new Plugin(this, options)); 
      } 
     }); 
    } 

})(jQuery, window, document); 

ahora tengo que añadir un método para esto, pero estoy bastante ni idea de cómo hacerlo.

El método debe funcionar de tal forma que una instancia de lo que el plugin crea en la página pueda tener una propiedad cambiada dinámicamente llamando al método con un valor a través de la consola (eventualmente esto ocurrirá a través de otro proceso) , pero la consola es buena por ahora).

¿Cómo podría modificar el código de arriba para permitir esto? ¿O estoy ladrando el árbol equivocado?

Cualquier ayuda sería muy apreciada, JavaScript complejo puede dejarme un poco perdido en la oscuridad a veces me temo, pero me gusta tratar de hacer las cosas como 'mejores prácticas' como sea posible.

Respuesta

12

La documentación de jQuery recomienda llamar a los métodos plugin pasar una cadena al método de complemento principal. Esto es para evitar que el espacio de nombres $.fn se vea saturado por los métodos de su complemento. Así se hace algo como esto:

$.fn.yourPlugin = function(options) { 
    if (typeof options === "string") { 
     //Call method referred to by 'options' 
    } else { 
     //Setup plugin as usual 
    } 
}; 

En su patrón, que ya tiene el lugar perfecto para definir sus métodos: Plugin.prototype. Por ejemplo, para agregar un método changeColor:

Plugin.prototype.changeColor = function(color) { 
    $(this.element).css("color", color); 
} 

Aviso el uso de $(this.element). Eso es porque en el Plugin constructor, una propiedad element se define, y el elemento sobre el que se está aplicando el plugin está asignado a la misma:

this.element = element; 

que es el elemento DOM real, no un objeto jQuery, de ahí la necesidad para llamar a jQuery en él.

Ahora que tiene un método, necesita agregar un mecanismo para llamarlo.Siguiendo las recomendaciones de la documentación de jQuery:

$.fn[pluginName] = function (options) { 
    return this.each(function() { 
     if (typeof options === "string") { 
      var args = Array.prototype.slice.call(arguments, 1), 
       plugin = $.data(this, 'plugin_' + pluginName); 
      plugin[options].apply(plugin, args); 
     } else if (!$.data(this, 'plugin_' + pluginName)) { 
      $.data(this, 'plugin_' + pluginName, 
      new Plugin(this, options)); 
     } 
    }); 
}; 

continuación, se puede llamar al método changeColor así:

$("#example").defaultPluginName("changeColour", "red");​​​​​​​​​​​​​​​​​​​​​​​​​​​ 

He aquí una fiddle with a working example. Es posible que desee agregar algo de control sobre el código de llamada al método para asegurarse de que el complemento se haya instanciado realmente en los elementos que lo está llamando.

+0

Esto se ve muy bien James. Le dará una oportunidad ahora y le responderá, pero muy prometedor. Gracias. –

+0

Esto funcionó para mí, por lo que marcar como respuesta. –

0

uso

Plugin.prototype.reset = function() { 

}; 
Plugin.prototype.destroy = function() { 

}; 

y así sucesivamente. añadir tantas opciones como desee

Cuestiones relacionadas