jquery jquery-plugins coffeescript destroy

No se puede destruir el plugin jQuery



jquery wrap (1)

Usted tiene algunas cosas extrañas sucediendo aquí, así que comenzaré en la parte superior.

Que CoffeeScript parece que ha transliterado un plugin jQuery existente de JavaScript a CoffeeScript. Debería escribir CoffeeScript en CoffeeScript:

class Plugin constructor: (@element, options) -> @options = $.extend { }, defaults, options #... @init() init: -> @bind() @setHeight() # The `return` is implicit here bind: -> # Use `=>` instead of an explicit `self = this` trick. $(window).on ''resize orientationchange'', => @setHeight() $(window).on ''touchstart'', => @unbind() #...

Ahora para la definición del plugin actual:

$.fn[pluginName] = ( options ) -> return this.each -> if !$.data(this, ''plugin_'' + pluginName) $.data(this, ''plugin_'' + pluginName) new Plugin(this, options)

La llamada $.data dentro de if no hace nada útil, quiere la forma $.data(obj, key, value) de $.data si su intención es adjuntar la instancia del Plugin al nodo DOM. Y de nuevo, no necesita los return y @ es más común que this en CoffeeScript:

$.fn[pluginName] = (options) -> @each -> if !$.data(@, "plugin_#{pluginName}") $.data(@, "plugin_#{pluginName}", new Plugin(@, options))

También cambié a interpolación de cadenas en lugar de + para la clave $.data , que generalmente es más fácil de leer.

Ahora deberías poder decir:

$(''.js-target'').data(''plugin_fullscreen'').destroy()

Tenga en cuenta que la clave de datos es ''plugin_fullscreen'' lugar de ''fullscreen'' . Esto es un poco desagradable, por supuesto, probablemente no quieras forzar a todos a mirar detalles privados.

Si quieres hacer cosas estilo jQuery-UI como:

$(''.js-target'').fullscreen(''destroy'')

entonces todo lo que tiene que hacer es actualizar la función de complemento para saber que se supone que ''destroy'' es una llamada de método en lugar de un objeto de options . Algo simple como esto debería ayudarte a comenzar:

$.fn[pluginName] = (args...) -> @each -> plugin = $.data(@, dataKey) if typeof args[0] == ''string'' plugin?[args[0]]?() else if !plugin $.data(@, dataKey, new Plugin(@, args[0]))

Entonces, si dices $(x).fullscreen(''string'') entonces asume que estás tratando de llamar a un método en la instancia interna de Plugin , todos los operadores existenciales ( ? ) Solo tratan con valores perdidos (complemento no conectado, método desconocido, ...); en la vida real, es posible que desee incluir en la lista blanca los métodos que puede llamar de esta manera. Y si dices $(x).fullscreen(opt: 1) entonces asume que estás tratando de adjuntar el complemento a algo usando {opt: 1} como las opciones. Nuevamente, una versión real de esto probablemente sería más complicada.

Demostración Quick''n''dirty: http://jsfiddle.net/ambiguous/568SU/1/

Es posible que desee ver la fábrica de widgets jQuery-UI si está haciendo mucho de este tipo de cosas, la fábrica se encarga de muchos de los detalles desagradables para usted.

He estado trabajando en algunos javascript para un proyecto y decidí que debería ser un plugin jQuery. He escrito algunas antes, pero esto necesita ser más robusto y destruible. Para ese fin he seguido algunos tutoriales pero todos se quedan cortos al describir cómo destruir el complemento.

Entonces, ¿cómo destruyo el plugin? Parece que no puedo acceder $(''.js-target).fullscreen(''destroy'') no parece funcionar. Tampoco lo hace $(.js-target).data(''fullscreen'').destroy() que devuelve TypeError: Cannot read property ''destroy'' of undefined en la consola.

Lo he escrito en coffeescript. El javascript generado se publica a continuación.

(($, window) -> ''use strict'' # Create the defaults once pluginName = ''fullscreen'' defaults = reference: window offset: 0 debug: true # The actual plugin constructor Plugin = ( element, options ) -> this.element = element this.options = $.extend {}, defaults, options this._defaults = defaults this._name = pluginName this.init() Plugin.prototype.init = -> this.bind() this.setHeight() Plugin.prototype.bind = -> # Maintain the scope self = this # Trigger on resize $(window).on ''resize orientationchange'', -> self.setHeight() # When scrolling on a touchscreen # prevent further resizes due to address bar shrinking $(window).on ''touchstart'', -> self.unbind() Plugin.prototype.getHeight = -> this.log ''Get height from: '', this.options.reference $( this.options.reference ).height() Plugin.prototype.setHeight = -> if this.options.offset == parseInt( this.options.offset ) offset = this.options.offset else offset = 0 $(this.element).css ''min-height'' : this.getHeight() - offset Plugin.prototype.unbind = -> this.log ''Unbind the resize, touchstart and orientationchange event handlers'' $(window).off ''resize touchstart orientationchange'' Plugin.prototype.destroy = -> this.unbind() log ''Remove any heights set on'', this.element $(this.element).attr(''style'','''') Plugin.prototype.log = ( msg, object ) -> if this.options.debug if !object object = '''' console.log( pluginName + '': '' + msg, object ) # A really lightweight plugin wrapper around the constructor, # preventing multiple instantiations $.fn[pluginName] = ( options ) -> return this.each -> if !$.data(this, ''plugin_'' + pluginName) $.data(this, ''plugin_'' + pluginName) new Plugin(this, options) return $.fn[pluginName] ) jQuery, window

Este es el javascript generado. ¿Podría ser la función anónima que coffeescript envuelve la función?

(function(){ (function($, window) { ''use strict''; var Plugin, defaults, pluginName; pluginName = ''fullscreen''; defaults = { reference: window, offset: 0, debug: true }; Plugin = function(element, options) { this.element = element; this.options = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; return this.init(); }; Plugin.prototype.init = function() { this.bind(); return this.setHeight(); }; Plugin.prototype.bind = function() { var self; self = this; $(window).on(''resize orientationchange'', function() { return self.setHeight(); }); return $(window).on(''touchstart'', function() { return self.unbind(); }); }; Plugin.prototype.getHeight = function() { this.log(''Get height from: '', this.options.reference); return $(this.options.reference).height(); }; Plugin.prototype.setHeight = function() { var offset; if (this.options.offset === parseInt(this.options.offset)) { offset = this.options.offset; } else { offset = 0; } return $(this.element).css({ ''min-height'': this.getHeight() - offset }); }; Plugin.prototype.unbind = function() { this.log(''Unbind the resize, touchstart and orientationchange event handlers''); return $(window).off(''resize touchstart orientationchange''); }; Plugin.prototype.destroy = function() { this.unbind(); log(''Remove any heights set on'', this.element); return $(this.element).attr(''style'', ''''); }; Plugin.prototype.log = function(msg, object) { if (this.options.debug) { if (!object) { object = ''''; } return console.log(pluginName + '': '' + msg, object); } }; $.fn[pluginName] = function(options) { return this.each(function() { if (!$.data(this, ''plugin_'' + pluginName)) { $.data(this, ''plugin_'' + pluginName); return new Plugin(this, options); } }); }; return $.fn[pluginName]; })(jQuery, window); }).call(this);

Cualquier ayuda sería apreciada.