第一个jQuery插件 - 如何处理重新初始化时的事件

First jQuery plugin- How to handle events on re-initialization?

本文关键字:初始化 事件 处理 插件 jQuery 何处理 第一个      更新时间:2023-09-26

嗯,这不是我的第一个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);

其他资源
插件演示
插件文档和完整源代码

解开旧事件的绑定有些丑陋。我在这里做错了什么还是总是需要的?

你应该防止在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"后重新初始化,这也方便地删除了事件侦听器。

下面是一个非常标准的销毁方法的示例实现:

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;
};