嗯,这不是我的第一个jQuery插件,但我认为其他人会受益。所以对我来说,它是第一次确保每个可能的应用程序按预期工作。
我的插件处理模态较少的叠加,因此必须侦听一些事件。如果插件被重新初始化,那么旧的听众似乎仍然存在并导致故障。
我的解决方案如下:
var oldSettings = $(_this).data('mlOverlaySettings');
if(oldSettings) {
$(oldSettings.target).unbind('click.mlOverlay');
$(document).unbind('click.mlOverlay');
$(document).unbind('keyup.mlOverlay');
}
对我而言,似乎问题与使用$.data
函数保存插件状态以及未正确发布的引用有任何关系。
$(_this).data('mlOverlaySettings', settings);
$(_this).data('mlIsOverlayVisible', false);
其他资源
Plugin Demo
Plugin documentation and full source code
解除旧事件的绑定有点难看。我在这里做错了还是总是需要?
答案 0 :(得分:1)
您应该在jQuery样板方法中阻止重新初始化:
(function($) {
var PLUGIN_IDENTIFIER = "my-plugin";
...plugin definition etc
//jQuery boilerplate
$.fn.myPlugin = function(opts) {
return this.each(function() {
var instance = $(this).data(PLUGIN_IDENTIFIER);
//Prevent reinit on this element
if (!instance) {
instance = new MyPlugin(this, opts);
$(this).data(PLUGIN_IDENTIFIER, instance);
}
//Method call
if (typeof opts === "string") {
instance[opts].apply(instance, [].slice.call(arguments, 1));
}
});
};
})();
您应始终提供"destroy"
方法,以删除它添加的.data和事件侦听器。因此,只有在调用"destroy"
之后才能重新初始化,这样可以方便地删除事件监听器。
这是一个非常标准的destroy方法的示例实现:
function MyPlugin(element, opts) {
this.element = $(element);
this.opts = $.extend(defaults, $(element).data(), opts);
//Other instance state
//absolutely do not use $.data for this, you should only occupy one $.data
//slot for your plugin for the same reason you only occupy one slot on
//$.fn
}
MyPlugin.prototype.destroy = function() {
this.element.removeData(PLUGIN_IDENTIFIER);
this.element.off(".myplugin"); //Remove all events off the element that belong to the plugin's namespace
//.remove() any helper elements created by the plugin
this.element = null;
};