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.