【问题标题】:jQuery-UI Dialog Memory LeaksjQuery-UI 对话框内存泄漏
【发布时间】:2010-01-19 16:38:14
【问题描述】:

我正在使用 IE7 和一些 jQuery 对话框,每个打开的对话框都会出现大约 6meg 的泄漏。我假设它与闭包有关,但到目前为止,我为移除它们所做的一切都没有帮助。在这一点上,我认为我已经处理了所有的闭包,除了我传入的回调函数,但即使在对话框关闭和删除后它仍然泄漏 6 兆。相关源码为:

function DialogDestroyAndRemove(event) {
    $(event.target).dialog("destroy").remove();
}

function CallbackAndCloseDialog(event) {
    if (event.data.callback != undefined) {
        event.data.callback(event.data.callbackResponse);
    }
    $("#" + event.data.dialogId).unbind('dialogbeforeclose').dialog('close');
}

// alert dialog modal with ok button
function AlertDialog(dialogTitle, dialogText, callbackFunction) {
    // dynamically generate and add a div so we can create the pop-up
    $('body').append("<div id=\"alertDialog\" style=\"display:none;\" title=\"" + dialogTitle + "\">" + dialogText + "</div>");

    // define/configure the modal pop-up
    $("#alertDialog").dialog({
        draggable: false,
        resizable: false,
        modal: true,
        autoOpen: true,
        open: function() {
            $("#alertDialog").parents('.ui-dialog-buttonpane button:eq(0)')
            .focus() //focus so the button is highlighted by default
            .bind('click', {
                callback: callbackFunction,
                callbackResponse: 'OK',
                dialogId: 'alertDialog'
            }, CallbackAndCloseDialog);
        },
        overlay: { backgroundColor: '#000', opacity: 0.5 },
        buttons: { 'OK': function() { } }
    }).bind('dialogbeforeclose', function(event, ui) {
        // Close (X) button was clicked; NOT the OK button
        if (callbackFunction != undefined) {
            callbackFunction('cancel');
        }
        callbackFunction = null;
    }).bind('dialogclose', DialogDestroyAndRemove);
}

我在上面做的一件事是我不确定是否需要它,而不是在定义 OK 按钮时定义它的回调(因此由于它引用回调而有一个闭包)来使用 .bind 定义它一次对话框打开。我希望能够将回调作为数据的一部分传递给点击事件可能有助于消除关闭。

任何想法我可以改变什么来摆脱这个泄漏?

【问题讨论】:

    标签: jquery internet-explorer jquery-ui memory-leaks closures


    【解决方案1】:

    这实际上是由 jQuery UI 框架在显示模式时如何处理背景变灰造成的。如果我删除 modal = true 和覆盖属性,内存泄漏会下降到 ~100k。

    为了解决这个问题,我必须在没有模式选项的情况下制作对话框,然后自己添加一个 div 到页面(固定位置顶部、左侧、底部、右侧全部为 0,并带有交替的灰色像素和透明像素背景)和使用对话框下方的 zindex 显示和隐藏它。

    虽然它并不理想(默认的模态叠加看起来很漂亮且平滑),但总比我弹出的每个对话框泄漏那么多内存要好。

    【讨论】:

    • 这与 IE 处理 PNG 透明度的方式有关,这……太可怕了。如果您使用简单的彩色 IE 过滤器而不是图像,您可以获得一些效果而不会影响内存。在您的 jQuery.UI.css 中更改 .ui-widget-overlay 类并在 background: 声明中从 url( 中删除所有内容,这将导致单色半透明覆盖。
    • 似乎与 IE 一般如何处理透明度有关。我删除了背景的 URL 方面(只留下纯色),它仍然做到了。直到我删除了不透明度过滤器,它才消失了。
    • 实际上从我的对话框中删除 modal: true 将 IE 8 内存使用量减半(从 150 MB 到 70)。
    【解决方案2】:

    希望这会有所帮助,我为这个问题创建了一个扩展,当 modal = true 用于 jQuery UI 对话框时,我使用 jQuery 工具 (flowplayer) 公开插件。

    我会将 folhttp://jsfiddle.net/yZ56q/lowing 代码包含在一个单独的 .js 文件中,并确保在此站点之前包含 jQuery 工具公开插件...http://flowplayer.org/tools/download.html

    (function($) {
        var _init = $.ui.dialog.prototype._init;
        $.ui.dialog.prototype._init = function() {
            var self = this;
            _init.apply(this, arguments);
    
            // Remove the default modal behavior and exhibit the new one
            if (self.options.modal) {
                self.options.modal = false;
                self.options.isModal = true;
            }
    
            this.uiDialog.bind('dialogopen', function(event, ui) {
                if (self.options.isModal) {
                    if ($(this).expose == null)
                        window.alert("Dialog box depends on the expose plugin to be modal. Please include the jquery tools Javascript include.");
                    else {
                        $(this).expose({ opacity: 0.3
                                , color: '#CCCCCC'
                                , loadSpeed: 0
                                , closeSpeed: 0
                                , closeOnClick: false
                                , closeOnEsc: false
                                , api: true
                        }).load();
                    }
                }
            });
    
            this.uiDialog.bind('dialogfocus', function(event, ui) {
                if (self.options.isModal) {
                    $(this).css('z-index', '9999');
                }
            });
    
            this.uiDialog.bind('dialogclose', function(event, ui) {
                if (self.options.isModal) {
                    if ($(this).expose != null) {
                        $(this).expose({ api: true }).close();
                    }
                }
            });
        };
    
            $.ui.dialog.defaults.isModal = false;
    })(jQuery);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2011-09-02
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多